曲靖做网站价格,上海市网站,网站建设合同交印花税,建设银行建湖支行官方网站文章目录 1.理论介绍2. 代码实现2.1. 主要代码2.2. 完整代码2.3. 输出结果 3. QA3.1. 运行过程中出现以下警告#xff1a;3.2. 定义的神经网络中的nn.Flatten()的作用是什么#xff1f;3.3. num_workers有什么作用#xff1f;它的值怎么确定#xff1f; 1.理论介绍
背… 文章目录 1.理论介绍2. 代码实现2.1. 主要代码2.2. 完整代码2.3. 输出结果 3. QA3.1. 运行过程中出现以下警告3.2. 定义的神经网络中的nn.Flatten()的作用是什么3.3. num_workers有什么作用它的值怎么确定 1.理论介绍
背景 在分类问题中模型的输出层是全连接层每个类别对应一个输出。我们希望模型的输出 y ^ j \hat{y}_j y^j可以视为属于类 j j j的概率然后选择具有最大输出值的类别作为我们的预测。 softmax函数能够将未规范化的输出变换为非负数并且总和为1同时让模型保持可导的性质而且不会改变未规范化的输出之间的大小次序。softmax函数 y ^ s o f t m a x ( o ) \mathbf{\hat{y}}\mathrm{softmax}(\mathbf{o}) y^softmax(o)其中 y ^ j e x p ( o j ) ∑ k e x p ( o k ) \hat{y}_j\frac{\mathrm{exp}({o_j})}{\sum_{k}\mathrm{exp}({o_k})} y^j∑kexp(ok)exp(oj)softmax是一个非线性函数但softmax回归的输出仍然由输入特征的仿射变换决定因此softmax回归是一个线性模型。为了避免将softmax的输出直接送入交叉熵损失造成的数值稳定性问题需要将softmax和交叉熵损失结合在一起具体做法是不将softmax概率传递到损失函数中 而是在交叉熵损失函数中传递未规范化的输出并同时计算softmax及其对数。因此定义交叉熵损失函数时也进行了softmax运算。
2. 代码实现
2.1. 主要代码
criterion nn.CrossEntropyLoss(reductionnone)2.2. 完整代码
import torch
from torchvision.datasets import FashionMNIST
from torchvision import transforms
from torch.utils.data import DataLoader
from torch import nn
from tensorboardX import SummaryWriterdef load_dataset(batch_size, num_workers):加载数据集root ./datasettransform transforms.Compose([transforms.ToTensor()])mnist_train FashionMNIST(rootroot, trainTrue, transformtransform, downloadTrue)mnist_test FashionMNIST(rootroot, trainFalse, transformtransform, downloadTrue)dataloader_train DataLoader(mnist_train, batch_size, shuffleTrue, num_workersnum_workers)dataloader_test DataLoader(mnist_test, batch_size, shuffleFalse,num_workersnum_workers)return dataloader_train, dataloader_testdef init_network(net):初始化模型参数def init_weights(m):if type(m) nn.Linear:nn.init.normal_(m.weight, mean0, std0.01)nn.init.constant_(m.bias, val0)if isinstance(net, nn.Module):net.apply(init_weights)class Accumulator:在n个变量上累加def __init__(self, n):self.data [0.0] * ndef add(self, *args):self.data [a float(b) for a, b in zip(self.data, args)]def reset(self):self.data [0.0] * len(self.data)def __getitem__(self, idx):return self.data[idx]def accuracy(y_hat, y):计算预测正确的数量if len(y_hat.shape) 1 and y_hat.shape[1] 1:y_hat y_hat.argmax(axis1)cmp y_hat.type(y.dtype) yreturn float(cmp.type(y.dtype).sum())def train(net, dataloader_train, criterion, optimizer, device):训练模型if isinstance(net, nn.Module):net.train()train_metrics Accumulator(3) # 训练损失总和、训练准确度总和、样本数for X, y in dataloader_train:X, y X.to(device), y.to(device)y_hat net(X)loss criterion(y_hat, y)optimizer.zero_grad()loss.mean().backward()optimizer.step()train_metrics.add(float(loss.sum()), accuracy(y_hat, y), y.numel())train_loss train_metrics[0] / train_metrics[2]train_acc train_metrics[1] / train_metrics[2]return train_loss, train_accdef test(net, dataloader_test, device):测试模型if isinstance(net, nn.Module):net.eval()with torch.no_grad(): test_metrics Accumulator(2) # 测试准确度总和、样本数for X, y in dataloader_test:X, y X.to(device), y.to(device)y_hat net(X)test_metrics.add(accuracy(y_hat, y), y.numel())test_acc test_metrics[0] / test_metrics[1]return test_accif __name__ __main__:# 全局参数设置batch_size 256num_workers 3num_epochs 20learning_rate 0.1device torch.device(cuda if torch.cuda.is_available() else cpu)# 创建记录器writer SummaryWriter()# 加载数据集dataloader_train, dataloader_test load_dataset(batch_size, num_workers)# 定义神经网络net nn.Sequential(nn.Flatten(), nn.Linear(784, 10)).to(device)# 初始化神经网络init_network(net)# 定义损失函数criterion nn.CrossEntropyLoss(reductionnone)# 定义优化器optimizer torch.optim.SGD(net.parameters(), lrlearning_rate)for epoch in range(num_epochs):train_loss, train_acc train(net, dataloader_train, criterion, optimizer, device)test_acc test(net, dataloader_test, device)writer.add_scalars(metrics, {train_loss: train_loss, train_acc: train_acc, test_acc: test_acc}, epoch)writer.close() 2.3. 输出结果 3. QA
3.1. 运行过程中出现以下警告 UserWarning: The given NumPy array is not writeable, and PyTorch does not support non-writeable tensors. This means you can write to the underlying (supposedly non-writeable) NumPy array using the tensor. You may want to copy the array to protect its data or make it writeable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at …\torch\csrc\utils\tensor_numpy.cpp:180.) return torch.from_numpy(parsed.astype(m[2], copyFalse)).view(*s) 该警告的大致意思是给定的NumPy数组不可写并且PyTorch不支持不可写的张量。这意味着你可以使用张量写入底层假定不可写NumPy数组。在将数组转换为张量之前可能需要复制数组以保护其数据或使其可写。在本程序的其余部分此类警告将被抑制。因此需要修改C:\Users\%UserName%\anaconda3\envs\%conda_env_name%\lib\site-packages\torchvision\datasets\mnist.py的第498行将return torch.from_numpy(parsed.astype(m[2], copyFalse)).view(*s)中的False改成True。
3.2. 定义的神经网络中的nn.Flatten()的作用是什么
net nn.Sequential(nn.Flatten(), nn.Linear(784, 10)).to(device)nn.Flatten()的作用是将图像数据张量展成一维方便输入后续的全连接层。
3.3. num_workers有什么作用它的值怎么确定
num_workers表示加载batch数据的进程数num_workers0时只有主进程去加载batch数据。要实现多进程加载数据加载函数一定要位于if __name__ __main__下。一般开始是将num_workers设置为等于计算机上的CPU内核数量在此基础上尝试减少num_workers的值选择训练速度高时的值。查看CPU内核数量的方法“任务管理器 性能 CPU”。