Jovian
⭐️
Sign In
In [ ]:
from itertools import count
from collections import defaultdict
from scipy.sparse import csr
import numpy as np
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
import tensorflow as tf
from tqdm import tqdm_notebook as tqdm


def vectorize_dic(dic,ix=None,p=None,n=0,g=0):
    """
    dic -- dictionary of feature lists. Keys are the name of features
    ix -- index generator (default None)
    p -- dimension of feature space (number of columns in the sparse matrix) (default None)
    """
    if ix==None:
        ix = dict()

    nz = n * g

    col_ix = np.empty(nz,dtype = int)

    i = 0
    for k,lis in dic.items():
        for t in range(len(lis)):
            ix[str(lis[t]) + str(k)] = ix.get(str(lis[t]) + str(k),0) + 1
            col_ix[i+t*g] = ix[str(lis[t]) + str(k)]
        i += 1

    row_ix = np.repeat(np.arange(0,n),g)
    data = np.ones(nz)
    if p == None:
        p = len(ix)

    ixx = np.where(col_ix < p)
    return csr.csr_matrix((data[ixx],(row_ix[ixx],col_ix[ixx])),shape=(n,p)),ix


def batcher(X_, y_=None, batch_size=-1):
    n_samples = X_.shape[0]

    if batch_size == -1:
        batch_size = n_samples
    if batch_size < 1:
       raise ValueError('Parameter batch_size={} is unsupported'.format(batch_size))

    for i in range(0, n_samples, batch_size):
        upper_bound = min(i + batch_size, n_samples)
        ret_x = X_[i:upper_bound]
        ret_y = None
        if y_ is not None:
            ret_y = y_[i:i + batch_size]
            yield (ret_x, ret_y)


cols = ['user','item','rating','timestamp']

train = pd.read_csv('data/ua.base',delimiter='\t',names = cols)
test = pd.read_csv('data/ua.test',delimiter='\t',names = cols)

x_train,ix = vectorize_dic({'users':train['user'].values,
                            'items':train['item'].values},n=len(train.index),g=2)


x_test,ix = vectorize_dic({'users':test['user'].values,
                           'items':test['item'].values},ix,x_train.shape[1],n=len(test.index),g=2)


print(x_train)
y_train = train['rating'].values
y_test = test['rating'].values

x_train = x_train.todense()
x_test = x_test.todense()

print(x_train)

print(x_train.shape)
print (x_test.shape)


n,p = x_train.shape

k = 10

x = tf.placeholder('float',[None,p])

y = tf.placeholder('float',[None,1])

w0 = tf.Variable(tf.zeros([1]))
w = tf.Variable(tf.zeros([p]))

v = tf.Variable(tf.random_normal([k,p],mean=0,stddev=0.01))

#y_hat = tf.Variable(tf.zeros([n,1]))

linear_terms = tf.add(w0,tf.reduce_sum(tf.multiply(w,x),1,keepdimss=True)) # n * 1
pair_interactions = 0.5 * tf.reduce_sum(
    tf.subtract(
        tf.pow(
            tf.matmul(x,tf.transpose(v)),2),
        tf.matmul(tf.pow(x,2),tf.transpose(tf.pow(v,2)))
    ),axis = 1 , keep_dims=True)


y_hat = tf.add(linear_terms,pair_interactions)

lambda_w = tf.constant(0.001,name='lambda_w')
lambda_v = tf.constant(0.001,name='lambda_v')

l2_norm = tf.reduce_sum(
    tf.add(
        tf.multiply(lambda_w,tf.pow(w,2)),
        tf.multiply(lambda_v,tf.pow(v,2))
    )
)

error = tf.reduce_mean(tf.square(y-y_hat))
loss = tf.add(error,l2_norm)


train_op = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)


epochs = 10
batch_size = 1000

# Launch the graph
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)

    for epoch in tqdm(range(epochs), unit='epoch'):
        perm = np.random.permutation(x_train.shape[0])
        # iterate over batches
        for bX, bY in batcher(x_train[perm], y_train[perm], batch_size):
            _,t=sess.run([train_op,loss], feed_dict={x: bX.reshape(-1, p), y: bY.reshape(-1, 1)})
            print(t)


    errors = []
    for bX, bY in batcher(x_test, y_test):
        errors.append(sess.run(error, feed_dict={x: bX.reshape(-1, p), y: bY.reshape(-1, 1)}))
        print(errors)
    RMSE = np.sqrt(np.array(errors).mean())
    print (RMSE)
In [1]:
#必要的第三方库
import torch
import torchvision
from torchvision.datasets import  MNIST
In [2]:
#下载数据集
dataset = MNIST (root = 'data/', download = True)

In [3]:
#创建测试集
test_dataset = MNIST(root = 'data/', train = False)

In [4]:
#查看一下训练集和测试集大小
print(test_dataset,'\n')
dataset[0]
Dataset MNIST Number of datapoints: 10000 Split: test Root Location: data/ Transforms (if any): None Target Transforms (if any): None
Out[4]:
(<PIL.Image.Image image mode=L size=28x28 at 0x2904A1F7160>, 5)
In [5]:
import matplotlib.pyplot as plt
%matplotlib inline
In [6]:
#可视化显示我们的数据
image , label = dataset[0]
plt.imshow(image)
print('Label:', label)
Label: 5
Notebook Image
In [7]:
#这些数据要转化成计算机理解的数据:矩阵向量
import torchvision.transforms as transforms
In [8]:
dataset = MNIST(root = 'data/',
               train = True,
               transform = transforms.ToTensor())
In [9]:
img_tensor, label = dataset[0]
print(img_tensor.shape,label)
torch.Size([1, 28, 28]) 5
In [10]:
#图像变成了1*28*28的张量;因为MNIST 的图象是灰度图像,因此,第一列只有一个一个通道,某些图像会有三个通道。我们来看看这些张量中的样本值
print(img_tensor[:10:15,10:15])
print(torch.max(img_tensor),torch.min(img_tensor))
tensor([[[0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0549, 0.0039, 0.6039, 0.9922, 0.3529, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000], [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.5451, 0.9922, 0.7451, 0.0078, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000], [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0431, 0.7451, 0.9922, 0.2745, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000], [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1373, 0.9451, 0.8824, 0.6275, 0.4235, 0.0039, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000], [0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3176, 0.9412, 0.9922, 0.9922, 0.4667, 0.0980, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000]]]) tensor(1.) tensor(0.)
In [11]:
#这些取值范围在[0:1]之间,代表不同程度的灰度,0表示黑,1表示白。
#我们使用plt.imshow将张量绘制成图像形式
plt.imshow(img_tensor[0],cmap = 'gray')
Out[11]:
<matplotlib.image.AxesImage at 0x2904f3665f8>
Notebook Image

#构建真实世界的机器学习模型,将数据分为三部分: 1.训练集 2.验证集 3.测试集

In [12]:
import numpy as np

#函数可以随机的混洗数组索引0,1,。。。n-1,并从中分出所需的比例作为验证集,在创建验证集之前,混洗索引是很重要的
#因为训练图像通常是按照目标标签排序的,即先是0的图像,然后是1的图像,2的图像....,如果我们选择最后20%的图像作为验证集
#则该验证集将仅包含8,9的图像,而训练集中又没有8,9的图像,使用这样的训练集是不可能得到好模型的,也不可能在真实数据集上取得好成绩。

def split_indices(n,val_pct):
    #测试集大小
    n_val = int(val_pct * n )
    
    #创造一个0 - n-1 的随机排列
    idxs = np.random.permutation(n)
    
    return idxs[n_val :],idxs[: n_val]
In [13]:
train_indices, val_indices = split_indices(len(dataset),val_pct = .2)
print(len(train_indices),len(val_indices))
print('简单的验证集:',val_indices[:20])
48000 12000 简单的交叉验证: [59164 9778 52025 19131 46211 7445 18448 50533 14339 55094 20174 37602 36770 31107 33876 59780 42673 46104 3162 57510]
In [14]:
#我们已经随机混洗了索引,并选择了一小部分(20%)作为验证集。现在我们可以使用SubsetRandomSampler 为它们中的每一个创建
#Pytorch数据加载器,它可从给定的索引列表随机地采用元素,创建分批数据。
from torch.utils.data.sampler import SubsetRandomSampler
from torch.utils.data.dataloader import DataLoader
In [17]:
batch_size = 100
#training sampler and data loader
train_sampler = SubsetRandomSampler(train_indices)
train_loader = DataLoader(dataset,batch_size,sampler=train_sampler)

#Validation sampler and data loader

val_sampler = SubsetRandomSampler(val_indices)
val_loader = DataLoader(dataset, batch_size,sampler=val_sampler)
In [18]:
import torch.nn as nn

input_size = 28*28  #size x需要展平成784大小的向量,传递给模型训练
num_classes = 10    #10分类

#Logistic regression pred = wx + b  

model = nn.Linear(input_size,num_classes)




In [20]:
print(model.weight.shape)
model.weight   #可以看到参数是一个矩阵形式
torch.Size([10, 784])
Out[20]:
Parameter containing:
tensor([[ 0.0017,  0.0214, -0.0029,  ..., -0.0245,  0.0205,  0.0204],
        [-0.0093,  0.0119, -0.0242,  ..., -0.0088,  0.0006, -0.0021],
        [-0.0144, -0.0154,  0.0340,  ..., -0.0212,  0.0047, -0.0293],
        ...,
        [-0.0310, -0.0248,  0.0105,  ..., -0.0172, -0.0122,  0.0154],
        [-0.0002, -0.0103,  0.0227,  ..., -0.0084,  0.0030, -0.0109],
        [-0.0231, -0.0284, -0.0007,  ..., -0.0013,  0.0163,  0.0089]],
       requires_grad=True)
In [21]:
print(model.bias.shape)

model.bias
torch.Size([10])
Out[21]:
Parameter containing:
tensor([-0.0289, -0.0245,  0.0042, -0.0174, -0.0084,  0.0232, -0.0220, -0.0213,
        -0.0278,  0.0166], requires_grad=True)
In [23]:
#我们将100张图片传入我们的模型中,为了使我们的模型处理784size的向量,需要将我们的model 改写一下,同时又不会改变底层数据
class MnistModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(input_size,num_classes)
    def forward(self,xb):
        xb = xb.reshape(-1,784)
        out = self.linear(xb)
        return out
model = MnistModel()

xb.reshape(-1 , 2828)的意思是我们想要xb张量的二维视图,其中沿第二个维度的长度是2828(即784)。.reshape的一个参数可以设置成-1,以让Pytorch根据 原始张量的形状自动找到它。

注意这个模型不再有.weight和.bias的属性,但有可返回包含权重和偏置的列表的.parameters方法,并且可以被Pytorch优化器使用。

In [25]:
print(model.linear.weight.shape,model.linear.bias.shape)
list(model.parameters())
torch.Size([10, 784]) torch.Size([10])
Out[25]:
[Parameter containing:
 tensor([[ 0.0060,  0.0009, -0.0126,  ...,  0.0277,  0.0350, -0.0312],
         [-0.0281, -0.0318,  0.0316,  ...,  0.0129, -0.0342,  0.0195],
         [-0.0280,  0.0201,  0.0165,  ..., -0.0126,  0.0118,  0.0233],
         ...,
         [-0.0173,  0.0196, -0.0188,  ..., -0.0161, -0.0294,  0.0093],
         [ 0.0211, -0.0297, -0.0035,  ..., -0.0136, -0.0238,  0.0344],
         [ 0.0141, -0.0113,  0.0157,  ...,  0.0036, -0.0336,  0.0051]],
        requires_grad=True), Parameter containing:
 tensor([ 0.0237,  0.0202,  0.0283,  0.0232,  0.0106, -0.0032,  0.0050,  0.0280,
          0.0175,  0.0236], requires_grad=True)]
In [26]:
#让我们训练一下看看结果
for images, labels in train_loader:
    outputs = model(images)
    break
print('output.shape:',outputs.shape)
print('Sample outputs:\n',outputs[:2].data)
output.shape: torch.Size([100, 10]) Sample outputs: tensor([[ 0.0776, 0.2690, 0.1750, 0.3892, 0.1841, -0.2113, 0.0145, 0.1466, 0.3243, 0.2175], [ 0.1689, -0.1725, 0.2457, 0.4073, -0.1633, -0.2099, 0.3711, -0.2306, 0.4290, -0.1543]])
In [29]:
#使用softmax 归一化输出
import torch.nn.functional as F

probs = F.softmax(outputs,dim = 1 )
print('sample probabilities :\n', probs[:2].data)
print('sum:',torch.sum(probs[0]).item())
sample probabilities : tensor([[0.0911, 0.1103, 0.1004, 0.1244, 0.1013, 0.0682, 0.0855, 0.0976, 0.1166, 0.1047], [0.1066, 0.0758, 0.1151, 0.1353, 0.0765, 0.0730, 0.1305, 0.0715, 0.1383, 0.0772]]) sum: 1.0
In [30]:
#最后,我们只需选择每个输出行中概率最高的元素的索引,确定每张图的预测标签,这里可以使用torch.max完成。

max_probs , preds = torch.max(probs,dim = 1)

print(preds)
tensor([3, 8, 8, 6, 0, 8, 8, 6, 8, 8, 8, 0, 8, 8, 8, 8, 2, 0, 8, 8, 6, 3, 8, 8, 8, 8, 3, 0, 8, 8, 8, 2, 3, 8, 8, 3, 8, 1, 0, 0, 0, 8, 8, 8, 8, 8, 1, 3, 9, 4, 8, 8, 8, 0, 8, 0, 8, 0, 8, 8, 0, 8, 1, 3, 8, 9, 8, 1, 0, 6, 8, 8, 2, 1, 8, 3, 8, 6, 8, 0, 0, 8, 8, 8, 6, 6, 3, 8, 3, 6, 2, 1, 3, 8, 1, 8, 4, 0, 1, 3])
In [31]:
labels
Out[31]:
tensor([8, 0, 6, 2, 2, 8, 0, 0, 2, 0, 0, 4, 6, 4, 5, 6, 7, 1, 0, 0, 2, 9, 6, 5,
        3, 4, 9, 2, 3, 5, 1, 7, 9, 7, 7, 6, 9, 5, 2, 7, 9, 0, 3, 8, 1, 1, 5, 1,
        8, 8, 3, 8, 7, 6, 1, 1, 2, 1, 5, 9, 2, 8, 4, 1, 0, 8, 8, 8, 6, 7, 3, 7,
        7, 8, 8, 8, 8, 2, 3, 7, 7, 8, 3, 8, 0, 6, 8, 6, 0, 3, 9, 8, 5, 1, 6, 1,
        9, 9, 3, 0])
In [32]:
#可以看出来预测和实际标签差别非常大,这说明随机初始化w和b是不够的,还需要调整权重和偏置。

def accuracy(l1,l2):
    return torch.sum(l1==l2).item() / len(l1)
In [33]:
accuracy(preds,labels)
Out[33]:
0.1

分类问题常用的一种损失函数是交叉熵,它的公式如下: 对于每个输出行,选取正确标签的预测概率,然后求所选概率的对数,最后,在在所有行上取交叉熵的平均,得到一批数据的整体损失。 交叉熵是一种连续且可微分的函数,并且能为模型的逐步改进提供良好的的反馈。

In [34]:
loss_fn = F.cross_entropy
loss = loss_fn(outputs,labels)
print(loss)


tensor(2.3003, grad_fn=<NllLossBackward>)
In [35]:
learning_rate = 0.001
optimizer = torch.optim.SGD(model.parameters(),lr = learning_rate)

我们定义一个函数loss_batch,其作用是: 计算一批数据的损失 如果提供了优化器,则选择性的执行梯度下降更新步骤 使用了预测结果和实际目标选择性地计算一个指标(比如准确度)

In [40]:
def loss_batch(model , loss_func, xb, yb, opt = None,metric = None):
    #计算损失
    preds  = model(xb)
    loss = loss_func(preds,yb)
    
    if opt is not None:
        #计算梯度
        loss.backward()
        opt.step()
        opt.zero_grad()
        
    metric_result = None
    if metric is not None:
        metric_result = metric(preds,yb)
    return loss.item(),len(xb),metric_result
In [70]:
def evaluate(model, loss_fn, valid_dl,metric = None):
    with torch.no_grad():
        results = [loss_batch(model, loss_fn, xb ,  yb, metric = metric ) for xb,yb in valid_dl]
        
        losses,nums,metrics = zip(*results)
        
        total = np.sum(nums)
        
        total_loss = np.sum(np.multiply(losses,nums))
        
        avg_loss = total_loss/total
        
        avg_metric = None
        
        if metric is not None:
            tot_metric = np.sum(np.multiply(metrics,nums))
            avg_metric = tot_metric/total
    return avg_loss, total, avg_metric

In [42]:
def accuracy(outputs, labels):
    _, preds = torch.max(outputs,dim = 1)
    return torch.sum(preds == labels).item() / len(preds)
In [72]:
val_loss,total,val_acc = evaluate(model ,loss_fn, val_loader, metric = accuracy)

print('loss:{:.4f},Accuracy :{:.4f}'.format(val_loss,val_acc))
loss:0.8146,Accuracy :0.8388
In [45]:
def fit (epochs, model, loss_fn, opt, train_dl, valid_dl, metric = None):
    for epoch in range(epochs):
        for xb,yb in train_dl:
            loss,_,_ = loss_batch(model , loss_fn, xb,yb, opt)
            
        result = evaluate(model,loss_fn,valid_dl,metric)
        val_loss,total,val_metric = result
        
        if metric is None:
            print('Epoch[{}/{}],Loss : {:.4f}'.format(epoch +1 , epochs, val_loss))
        else:
            print('Epoch[{}/{}],Loss : {:.4f},{},{:.4f}'.format(epoch +1 , epochs, val_loss,metric.__name__,val_metric))
In [46]:
#训练模型,训练5个epoch
model = MnistModel()

optimizer = torch.optim.SGD(model.parameters(),lr = learning_rate)

fit(5,model,F.cross_entropy,optimizer,train_loader,val_loader,accuracy)
Epoch[1/5],Loss : 1.8816,accuracy,0.6610 Epoch[2/5],Loss : 1.5815,accuracy,0.7539 Epoch[3/5],Loss : 1.3708,accuracy,0.7826 Epoch[4/5],Loss : 1.2191,accuracy,0.7990 Epoch[5/5],Loss : 1.1067,accuracy,0.8087
In [47]:
fit(5,model,F.cross_entropy,optimizer,train_loader,val_loader,accuracy)
Epoch[1/5],Loss : 1.0205,accuracy,0.8160 Epoch[2/5],Loss : 0.9527,accuracy,0.8225 Epoch[3/5],Loss : 0.8978,accuracy,0.8283 Epoch[4/5],Loss : 0.8526,accuracy,0.8327 Epoch[5/5],Loss : 0.8146,accuracy,0.8388
In [48]:
#replace these values with your results

accuracies = [0.0911,0.66100,0.7539,0.7826,0.7990,0.8087,0.8160,0.8225,0.8283,0.8327,0.8388]
plt.plot(accuracies,'-x')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.title('Accuracy vs. No. of epoch');
Notebook Image

尽管我们现在已经跟踪了模型的整体准确度,但也可了解一下模型在某些样本上的表现。

In [50]:
test_dataset = MNIST(root = 'data/',train = False,transform  = transforms.ToTensor())
In [53]:
img, label = test_dataset[0]
plt.imshow(img[0],cmap = 'gray')
print('Shape:', img.shape)
print('Label:', label)


Shape: torch.Size([1, 28, 28]) Label: 7
Notebook Image
In [58]:
def predict_image(img, model):
    xb = img.unsqueeze(0)
    yb = model(xb)
    _,preds = torch.max(yb,dim = 1)
    return preds[0]
In [59]:
img, label = test_dataset[0]
plt.imshow(img[0],cmap = 'gray')

print('Label:',label ,', Predicted:',predict_image(img,model))
Label: 7 , Predicted: tensor(7)
Notebook Image
In [60]:
img, label = test_dataset[10]
plt.imshow(img[0],cmap = 'gray')

print('Label:',label ,', Predicted:',predict_image(img,model))
Label: 0 , Predicted: tensor(0)
Notebook Image
In [61]:
img, label = test_dataset[20]
plt.imshow(img[0],cmap = 'gray')

print('Label:',label ,', Predicted:',predict_image(img,model))
Label: 9 , Predicted: tensor(9)
Notebook Image
In [62]:
img, label = test_dataset[30]
plt.imshow(img[0],cmap = 'gray')

print('Label:',label ,', Predicted:',predict_image(img,model))
Label: 3 , Predicted: tensor(3)
Notebook Image
In [65]:
img, label = test_dataset[1899]
plt.imshow(img[0],cmap = 'gray')

print('Label:',label ,', Predicted:',predict_image(img,model))
Label: 8 , Predicted: tensor(3)
Notebook Image

最后,我们在测试集上看看模型的整体损失和准确度

In [75]:
test_loader = DataLoader(test_dataset,batch_size = 200)
val_loss,total,val_acc == evaluate(model, loss_fn, test_loader, metric = accuracy)
print('Loss {:.4f}, Accuracy: {:.4f}'.format(val_loss,val_acc))
Loss 0.8146, Accuracy: 0.8388

为了防止我们的模型流失,毕竟训练了很长时间,我们也要学会保存我们的模型

In [76]:
torch.save(model.state_dict(),'mnist-logistic.pth')
In [77]:
model.state_dict()  #训练好的模型及其参数
Out[77]:
OrderedDict([('linear.weight',
              tensor([[-1.7306e-02,  6.7846e-03, -2.1972e-03,  ...,  2.4542e-03,
                        3.0646e-02,  3.1558e-02],
                      [-1.5134e-02, -1.4300e-02,  3.0489e-03,  ...,  1.2004e-02,
                        3.0561e-02, -2.9647e-02],
                      [-5.1982e-03,  3.5285e-02,  1.8464e-02,  ..., -1.5213e-02,
                        1.4901e-07,  3.4109e-02],
                      ...,
                      [-2.4026e-02,  3.7099e-03,  2.0386e-02,  ..., -6.4378e-03,
                       -3.5180e-02, -5.7706e-03],
                      [-2.5936e-02, -1.1674e-02,  3.0901e-02,  ..., -2.3123e-02,
                       -2.7726e-02, -2.0014e-03],
                      [-6.2846e-03, -2.4796e-02, -2.7715e-02,  ..., -3.3019e-02,
                       -1.5695e-02,  2.3223e-02]])),
             ('linear.bias',
              tensor([-0.0309,  0.0573, -0.0480, -0.0331,  0.0345,  0.0300, -0.0189,  0.0390,
                      -0.0464, -0.0175]))])

要加载该模型的权重,我们可以实例化MnistModel类的一个对象,并使用.load_state_dict方法

In [78]:
model2 = MnistModel()
model2.load_state_dict(torch.load('mnist-logistic.pth'))
model2.state_dict()
Out[78]:
OrderedDict([('linear.weight',
              tensor([[-1.7306e-02,  6.7846e-03, -2.1972e-03,  ...,  2.4542e-03,
                        3.0646e-02,  3.1558e-02],
                      [-1.5134e-02, -1.4300e-02,  3.0489e-03,  ...,  1.2004e-02,
                        3.0561e-02, -2.9647e-02],
                      [-5.1982e-03,  3.5285e-02,  1.8464e-02,  ..., -1.5213e-02,
                        1.4901e-07,  3.4109e-02],
                      ...,
                      [-2.4026e-02,  3.7099e-03,  2.0386e-02,  ..., -6.4378e-03,
                       -3.5180e-02, -5.7706e-03],
                      [-2.5936e-02, -1.1674e-02,  3.0901e-02,  ..., -2.3123e-02,
                       -2.7726e-02, -2.0014e-03],
                      [-6.2846e-03, -2.4796e-02, -2.7715e-02,  ..., -3.3019e-02,
                       -1.5695e-02,  2.3223e-02]])),
             ('linear.bias',
              tensor([-0.0309,  0.0573, -0.0480, -0.0331,  0.0345,  0.0300, -0.0189,  0.0390,
                      -0.0464, -0.0175]))])

就像之前测试一样,我们看看保存下来的参数是否与之前训练的一样

In [79]:
val_loss,total,val_acc == evaluate(model, loss_fn, test_loader, metric = accuracy)
Out[79]:
(0.8145552088816961, 12000, array([False, False, False]))
In [80]:
import jovian
In [ ]:
jovian.commit()
[jovian] Saving notebook..
In [ ]: