b2 = torch.zeros(num_outputs, dtype=torch.float) # 将参数组成tensor params = [W1, b1, W2, b2] for p in params: # 批量设置参数的梯度设置 p.requires_grad_(requires_grad=True) def relu(X): # ReLU函数的设置 return torch.max(input=X, other=torch.tensor(0.0)) def net(X): # 把X扁平化 X = X.view((-1, num_featrues)) # 用ReLU函数对隐藏层的预测进行激活 H = relu(torch.matmul(X, W1) + b1) # 然后在应用输出层的参数 return torch.matmul(H, W2) + b2 # 定义交叉熵损失的函数指针 loss = torch.nn.CrossEntropyLoss() # 用之前定义好的train_ch3函数进行训练,这里学习率很高是因为需要乘上batch_size来稳住 # 本质上是Pytorch算法loss求和和求平均导致的(P81) num_epochs, lr = 5, 100.0 train.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)
""" 这一节也是试一下用神经网络模块来简洁实现多层感知机 """ # 多层感知机与之前softmax的区别就是多了个隐藏层 num_features, num_outputs, num_hiddens = 28 * 28, 10, 256 # 网络从上到下逐级深入 net = nn.Sequential( # 先用一层扁平层把输入的参数打平 # 扁平层主要意义是代替卷积层,相当于直接感受所有特征 layers.FlattenLayer(), # 然后用线性的全连接层连接到隐藏层 nn.Linear(num_features, num_hiddens), # 然后用ReLU激活 nn.ReLU(), # 再连接到全连接的输出层 nn.Linear(num_hiddens, num_outputs), ) # 对net中的每个参数都进行正态分布初始化 for p in net.parameters(): init.normal_(p, 0, 0.01) # 设置与读取 batch_size = 256 train_iter, test_iter = data_process.load_data_fashion_mnist(batch_size) loss = torch.nn.CrossEntropyLoss() optim = torch.optim.SGD(net.parameters(), 0.5) # 进行训练 num_epochs = 5 train.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optim)
return (y_hat.argmax(dim=1) == y).float().mean().item() # 这里输出可以看到,之前的预测值里取最大后y_hat预测了[2,2] # y是[0,2],所以预测正确的有一半,也即是0.5 print(accuracy(y_hat, y)) # 对测试集的准确率用前面完全随机的模型进行测试,约0.05的准确率 print(data_process.evaluate_accuracy(test_iter, net)) # 真正来训练softmax模型,仍然采用前面的小批梯度下降算法来优化 # 迭代次数 epoch_num = 5 # 学习率 learning_rate = 0.03 # 调用写好的train_ch3对这个softmax回归进行训练,注意这里带入了交叉熵作为代价函数 train.train_ch3(net, train_iter, test_iter, cross_entropy, epoch_num, batch_size, [W, b], learning_rate) # 最后对训练好的网络来实际预测一下看看真实的效果 # 随意从test中取一组数据出来 X, y = iter(test_iter).next() # 从下标值取出真实的标签名 true_labels = data_process.get_fashion_mnist_labels(y.numpy()) pred_labels = data_process.get_fashion_mnist_labels( net(X).argmax(dim=1).numpy()) # 设置好绘制的时候的标题,用一个数组内循环解决 # zip函数将可迭代的对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表 # 所以这里用zip把后面的标签数组转成了标签组形式 titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)] # 将对比图绘制出来 plot.show_fashion_mnist(X[0:9], titles[0:9])