我是一名小白,最近学习pytorch,用pytorch复现一下吴的课后编程作业
开始之前先导入库
import numpy as np import h5py import matplotlib.pyplot as plt import tf_utils import time import torch from torch import nn import torch.nn.functional as F
X_train_orig , Y_train_orig , X_test_orig , Y_test_orig , classes = tf_utils.load_dataset() X_train_flatten = X_train_orig.reshape(X_train_orig.shape[0],-1).T #每一列就是一个样本 X_test_flatten = X_test_orig.reshape(X_test_orig.shape[0],-1).T #归一化数据 X_train = X_train_flatten / 255 X_test = X_test_flatten / 255 #转换成tensor X_train = torch.tensor(X_train).float() X_test = torch.tensor(X_test).float() Y_train_orig = torch.tensor(Y_train_orig) Y_test_orig = torch.tensor(Y_test_orig)
Pytorch有自带的独热编码函数torch.nn.functional.one_hot()
#转换为独热矩阵 Y_train = F.one_hot(Y_train_orig,6).squeeze()#移除长度为1的维度 Y_test = F.one_hot(Y_test_orig,6).squeeze()
X_train=X_train.T X_test=X_test.T #网络为:12288-25-12-6 class Net(nn.Module): def __init__(self): super(Net,self).__init__() self.layer=nn.Sequential( nn.Linear(12288,25), nn.ReLU(), nn.Linear(25,12), nn.ReLU(), nn.Linear(12,6) ) def forward(self,x): x=self.layer(x) return x net=Net() loss=nn.CrossEntropyLoss() optimizer=torch.optim.SGD(net.parameters(),lr=0.001)
注意
nn.Linear线性变换公式是
nn.CrossEntropyLoss(input,target)损失函数target参数不需要传one_hot向量,否则会报错1D target tensor expected, multi-target not supported
def train(net,loss,optimizer,X_train,Y_train): for epoch in range(num_epochs): y=net(X_train) l=loss(input = y,target = Y_train_orig.squeeze())#input放的是独热编码,target放的是一维的label值 optimizer.zero_grad() l.backward() optimizer.step() train_loss = l.item() correct=(y.argmax(dim=1)==Y_train_orig).sum().item() if (epoch + 1) % 1000 == 0: y_test=net(X_test) correct_test = (y_test.argmax(dim=1) == Y_test_orig).sum().item() print( 'epoch {:d} loss={:.4f} 训练集正确率:{:.4f}% 测试集正确率:{:.4f}%'.format(epoch+1,train_loss,correct/X_train.shape[0]*100,correct_test/X_test.shape[0]*100) ) if __name__ =='__main__': num_epochs=10000 train(net,loss,optimizer,X_train,Y_train) torch.save(net, './model.pth') #保存模型
训练到35000次训练集正确率已经达到100%,到时测试集正确率只有88%,说明存在较大过拟合。
训练十万次的结果如下:
加载训练好的模型用自己的图片进行测试
my_image1 = "1.png"#定义图片名称 fileName1 = "./" + my_image1#图片地址 image1 =cv2.imread(fileName1)#读取图片 # plt.imshow(image1) # plt.show()#显示图片 my_image1 = image1.reshape(1,64 * 64 * 3) my_image1 = torch.tensor(my_image1).float() model = torch.load('./model.pth') #加载模型 out=model(my_image1) print(out)
运行结果:
测试结果来说不能说是不准确,但基本是毫不相关了......