我是一名小白,最近学习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)
运行结果:
测试结果来说不能说是不准确,但基本是毫不相关了......