网站开发成功案例,厦门专业做网站的,成绩查询系统网站开发,wordpress plugins目录 demo(Lenet)
代码实现基本步骤#xff1a;
TensorFlow
一、核心概念
二、主要特点
三、简单实现
参数:
模型编译
模型训练
模型评估
Alexnet
model.py
train.py
predict.py demo(Lenet)
PyTorch提供了一个名为“torchvision”的附加库#xff0c;其中包含…目录 demo(Lenet)
代码实现基本步骤
TensorFlow
一、核心概念
二、主要特点
三、简单实现
参数:
模型编译
模型训练
模型评估
Alexnet
model.py
train.py
predict.py demo(Lenet)
PyTorch提供了一个名为“torchvision”的附加库其中包含了各种预训练的模型和常用的数据集以及用于构建和训练计算机视觉模型的实用工具。
LeNet是一个经典的卷积神经网络架构用于手写数字识别任务如MNIST数据集。 pytorch tensor的通道排序[batch, channel, height, width]
Lenet是一个 7 层的神经网络包含 3 个卷积层2 个池化层1 个全连接层1个输出层。其中所有卷积层的卷积核都为 5x5步长1池化方法都为平均池化激活函数为 ReLu。图中最后一步是要和全连接层连接所以要转换为一维向量。函数用view。
代码实现基本步骤
model.py定义LeNet网络模型train.py加载数据集并训练计算loss和accuracy保存训练好的网络参数predict.py用自己的数据集进行分类测试
TensorFlow
TensorFlow是一个由谷歌开发的开源机器学习框架被广泛应用于构建和训练各种类型的机器学习模型。
一、核心概念
TensorFlow的核心概念是使用数据流图来表示数学计算的过程。数据流图由一系列节点和边组成的有向图其中节点表示数学计算操作而边则表示数据张量的流动。这种表示方式使得TensorFlow能够高效地处理复杂的数学计算和机器学习算法。
二、主要特点
灵活性TensorFlow支持动态图和静态图两种模式用户可以根据需要选择适合自己的开发模式。自动微分TensorFlow自带自动微分功能可以方便地计算模型的梯度这对于优化机器学习模型至关重要。分布式训练TensorFlow支持分布式训练可以在多台机器上分布式训练模型这对于处理大规模数据集和复杂模型非常有用。高级APITensorFlow提供了高级API如Keras可以方便地构建和训练模型。Keras已经发展成一个独立的深度学习框架并在TensorFlow 2.x版本中得到了更好的支持和集成。 ps:后面我们也会学习低级API需要手动定义输入Tensor、各个层的计算过程如卷积、激活、池化等并将这些计算过程组合成一个完整的计算图。部署和移动端支持TensorFlow支持将训练好的模型部署到生产环境和移动端方便用户在不同平台上进行应用。
三、简单实现
import tensorflow as tf from tensorflow.keras import layers, models # 加载和预处理数据这里以MNIST手写数字数据集为例 mnist tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) mnist.load_data() x_train, x_test x_train / 255.0, x_test / 255.0 # 归一化像素值到0-1之间 # 构建模型 model models.Sequential([ layers.Flatten(input_shape(28, 28)), # 将28x28的输入图像展平为一维向量 layers.Dense(128, activationrelu), # 全连接层128个神经元ReLU激活函数 layers.Dropout(0.2), # Dropout层用于减少过拟合丢弃20/神经元layers.Dense(10, activationsoftmax) # 输出层10个神经元对应10个类别softmax激活函数 ]) # 编译模型 model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) # 训练模型 model.fit(x_train, y_train, epochs5) # 评估模型 test_loss, test_acc model.evaluate(x_test, y_test, verbose2) print(f\nTest accuracy: {test_acc})
我们首先加载了MNIST数据集并将其分为训练集和测试集。接着我们对图像数据进行了归一化处理将像素值从0-255缩放到0-1之间。然后我们构建了一个简单的神经网络模型该模型包含一个展平层、一个全连接层带有ReLU激活函数、一个Dropout层用于减少过拟合和一个输出层带有softmax激活函数用于多分类任务。我们编译了模型指定了优化器Adam、损失函数稀疏分类交叉熵和评估指标准确率。最后我们训练了模型并在测试集上评估了其性能。
参数: layers.Flatten(input_shape(28, 28)): Flatten层用于将输入图像28x28像素展平为一维向量784个元素。这是必要的因为全连接层需要一维输入。 layers.Dense(10, activationsoftmax): 这是输出层具有10个神经元对应于10个数字类别。使用softmax激活函数将输出转换为概率分布。
模型编译 optimizeradam: 指定优化器为Adam。 losssparse_categorical_crossentropy: 指定损失函数为稀疏分类交叉熵。由于y_train和y_test是整数标签而不是one-hot编码因此使用稀疏版本。 metrics[accuracy]: 指定评估模型性能的指标为准确率。
模型训练
model.fit(x_train, y_train, epochs5): 使用训练数据x_train和y_train来训练模型训练5个周期epoch。每个周期都会遍历整个训练集一次。
模型评估 model.evaluate(x_test, y_test, verbose2): 使用测试数据x_test和y_test来评估模型的性能。verbose2表示在评估过程中显示每个批次的损失和准确率。
Alexnet ISLVRC 2012 训练集1,281,167张已标注图片 验证集50,000张已标注图片 测试集100,000张未标注图片 经卷积后的矩阵尺寸大小计算公式为 N (W − F 2P ) / S 1
① 输入图片大小 W(高)×W宽 ② Filter卷积核大小 F×F ③ 步长 S ④ padding的像素数 P 例如像卷积1中因为作者用了两个GPU我们只看一个。kernels48*2已知输入为[224,224,3(深度为3)]输出为55*55*9648*2高*宽*池化核数。 N (W − F 2P ) / S 1 [224-11(12)]/4155 代码示例 import torch.nn as nn import torch class AlexNet(nn.Module): def __init__(self, num_classes1000, init_weightsFalse): super(AlexNet, self).__init__() self.features nn.Sequential( nn.Conv2d(3, 48, kernel_size11, stride4, padding2), # input[3, 224, 224] output[48, 55, 55] nn.ReLU(inplaceTrue), nn.MaxPool2d(kernel_size3, stride2), # output[48, 27, 27] nn.Conv2d(48, 128, kernel_size5, padding2), # output[128, 27, 27] nn.ReLU(inplaceTrue), nn.MaxPool2d(kernel_size3, stride2), # output[128, 13, 13] nn.Conv2d(128, 192, kernel_size3, padding1), # output[192, 13, 13] nn.ReLU(inplaceTrue), nn.Conv2d(192, 192, kernel_size3, padding1), # output[192, 13, 13] nn.ReLU(inplaceTrue), nn.Conv2d(192, 128, kernel_size3, padding1), # output[128, 13, 13] nn.ReLU(inplaceTrue), nn.MaxPool2d(kernel_size3, stride2), # output[128, 6, 6] ) self.classifier nn.Sequential( nn.Dropout(p0.5), nn.Linear(128 * 6 * 6, 2048), nn.ReLU(inplaceTrue), nn.Dropout(p0.5), nn.Linear(2048, 2048), nn.ReLU(inplaceTrue), nn.Linear(2048, num_classes), ) if init_weights: self._initialize_weights() def forward(self, x): x self.features(x) x torch.flatten(x, start_dim1) x self.classifier(x) return x def _initialize_weights(self): for m in self.modules(): if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, modefan_out, nonlinearityrelu) if m.bias is not None: nn.init.constant_(m.bias, 0) elif isinstance(m, nn.Linear): nn.init.normal_(m.weight, 0, 0.01) nn.init.constant_(m.bias, 0)
model.py
这个文件一个用于图像分类的卷积神经网络模型。
初始化函数 __init__ num_classes模型输出的类别数默认为1000。init_weights一个布尔值指示是否在初始化时自动设置模型权重默认为False。self.features定义了模型的特征提取部分包括一系列的卷积层、ReLU激活函数和最大池化层。self.classifier定义了模型的分类部分包括全连接层、Dropout层和ReLU激活函数。如果init_weights为True则调用_initialize_weights函数来初始化权重。前向传播函数 forward 输入图像x通过self.features进行特征提取然后通过torch.flatten将特征图展平为一维向量。展平后的特征向量通过self.classifier进行分类输出每个类别的预测得分。权重初始化函数 _initialize_weights 遍历模型的所有模块如果模块是卷积层或全连接层则使用特定的方法初始化其权重和偏置。
import os import sys import json
import torch import torch.nn as nn from torchvision import transforms, datasets, utils import matplotlib.pyplot as plt import numpy as np import torch.optim as optim from tqdm import tqdm
from model import AlexNet
tqdm用于显示进度条。 from model import AlexNet导入了自定义的AlexNet模型。 def main(): device torch.device(cuda:0 if torch.cuda.is_available() else cpu) print(using {} device..format(device))
检查CUDA是否可用并据此选择使用GPU还是CPU。 data_transform { train: transforms.Compose([transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]), val: transforms.Compose([transforms.Resize((224, 224)), # cannot 224, must (224, 224) transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])}
定义了训练和验证数据的预处理步骤包括随机裁剪、水平翻转、调整大小、归一化 data_root os.path.abspath(os.path.join(os.getcwd(), ../..)) # get data root path image_path os.path.join(data_root, data_set, flower_data) # flower data set path assert os.path.exists(image_path), {} path does not exist..format(image_path) train_dataset datasets.ImageFolder(rootos.path.join(image_path, train), transformdata_transform[train])
使用datasets.ImageFolder加载训练和验证数据集。 类标签处理 train_num len(train_dataset) # {daisy:0, dandelion:1, roses:2, sunflower:3, tulips:4} flower_list train_dataset.class_to_idx cla_dict dict((val, key) for key, val in flower_list.items()) # write dict into json file json_str json.dumps(cla_dict, indent4) with open(class_indices.json, w) as json_file: json_file.write(json_str)
将类别索引映射到类别名称并保存到JSON文件中。 数据加载器 batch_size 32 nw min([os.cpu_count(), batch_size if batch_size 1 else 0, 8]) # number of workers print(Using {} dataloader workers every process.format(nw)) train_loader torch.utils.data.DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue, num_workersnw) validate_dataset datasets.ImageFolder(rootos.path.join(image_path, val), transformdata_transform[val])
创建数据加载器用于批量加载数据。 num_workers指定了加载数据时使用的进程数。 val_num len(validate_dataset) validate_loader torch.utils.data.DataLoader(validate_dataset, batch_size4, shuffleFalse, num_workersnw) print(using {} images for training, {} images for validation..format(train_num, val_num)) # test_data_iter iter(validate_loader) # test_image, test_label test_data_iter.next() # # def imshow(img): # img img / 2 0.5 # unnormalize # npimg img.numpy() # plt.imshow(np.transpose(npimg, (1, 2, 0))) # plt.show() # # print( .join(%5s % cla_dict[test_label[j].item()] for j in range(4))) # imshow(utils.make_grid(test_image))
模型、损失函数和优化器 net AlexNet(num_classes5, init_weightsTrue) net.to(device) #网络指定到我们设备中 loss_function nn.CrossEntropyLoss() # pata list(net.parameters()) optimizer optim.Adam(net.parameters(), lr0.0002)
初始化AlexNet模型并设置类别数为5。 将模型移动到指定的设备上GPU或CPU。 使用交叉熵损失函数。 使用Adam优化器。 epochs 10 save_path ./AlexNet.pth best_acc 0.0 train_steps len(train_loader) for epoch in range(epochs): # train net.train() running_loss 0.0 train_bar tqdm(train_loader, filesys.stdout) for step, data in enumerate(train_bar): images, labels data optimizer.zero_grad() outputs net(images.to(device)) loss loss_function(outputs, labels.to(device)) loss.backward() optimizer.step() # print statistics running_loss loss.item() train_bar.desc train epoch[{}/{}] loss:{:.3f}.format(epoch 1, epochs, loss) # validate net.eval() #在网络搭建过程中我们失去了一部分神经元但我们只希望在训练中不希望在预测过程中起作用 acc 0.0 # accumulate accurate number / epoch with torch.no_grad(): val_bar tqdm(validate_loader, filesys.stdout) for val_data in val_bar: val_images, val_labels val_data outputs net(val_images.to(device)) predict_y torch.max(outputs, dim1)[1] acc torch.eq(predict_y, val_labels.to(device)).sum().item() val_accurate acc / val_num print([epoch %d] train_loss: %.3f val_accuracy: %.3f % (epoch 1, running_loss / train_steps, val_accurate)) if val_accurate best_acc: best_acc val_accurate torch.save(net.state_dict(), save_path)
训练过程分为多个epoch。 在每个epoch中模型先切换到训练模式然后遍历训练数据集。 使用优化器更新模型参数。 每个epoch结束后模型切换到评估模式遍历验证数据集以计算准确率。 如果当前epoch的验证准确率高于之前的最高准确率则保存模型。 print(Finished Training) if __name__ __main__: main()
train.py
训练AlexNet模型的完整流程。
设置设备GPU或CPU。定义数据预处理流程data_transform包括随机裁剪、水平翻转、归一化等。设置数据集的路径并加载训练和验证数据集。将类别索引映射到类别名称并保存为JSON文件。配置数据加载器DataLoader包括批量大小、是否打乱数据、工作线程数等。初始化AlexNet模型设置损失函数交叉熵损失和优化器Adam。训练模型 在每个epoch中模型首先在训练集上进行训练计算损失并更新权重。然后在验证集上评估模型的准确性。记录每个epoch的训练损失和验证准确性。如果当前epoch的验证准确性高于之前的最佳准确性则保存模型权重。
import os import json
import torch from PIL import Image from torchvision import transforms import matplotlib.pyplot as plt
from model import AlexNet def main(): device torch.device(cuda:0 if torch.cuda.is_available() else cpu) data_transform transforms.Compose( [transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
定义了一个预处理管道它首先将图像调整到224x224像素AlexNet的输入大小然后将图像转换为PyTorch张量并对每个通道进行归一化处理。归一化使用均值(0.5, 0.5, 0.5)和标准差(0.5, 0.5, 0.5) # load image img_path rD:\pycharm\深度学习-图像分类\data_set\flower_data\train\tulips\11746276_de3dec8201.jpg assert os.path.exists(img_path), file: {} dose not exist..format(img_path) img Image.open(img_path) plt.imshow(img) # [N, C, H, W], img data_transform(img) # expand batch dimension img torch.unsqueeze(img, dim0)
将图像通过预处理管道并增加一个批量维度因为PyTorch模型期望输入是一个四维张量其中N是批量大小C是通道数H和W分别是高度和宽度。 # read class_indict json_path ./class_indices.json assert os.path.exists(json_path), file: {} dose not exist..format(json_path) with open(json_path, r) as f: class_indict json.load(f)
读取包含类别索引映射的JSON文件这个文件应该有一个从类别索引到类别名称的映射。 # create model model AlexNet(num_classes5).to(device) # load model weights weights_path ./AlexNet.pth assert os.path.exists(weights_path), file: {} dose not exist..format(weights_path) model.load_state_dict(torch.load(weights_path)) model.eval()
创建AlexNet模型实例指定类别数为5并将模型移动到之前设置的设备上GPU或CPU。然后加载预训练的权重并将模型设置为评估模式这意味着在推理期间不会进行梯度计算或权重更新。 with torch.no_grad(): # predict class output torch.squeeze(model(img.to(device))).cpu() predict torch.softmax(output, dim0) predict_cla torch.argmax(predict).numpy()
使用torch.no_grad()禁用梯度计算因为我们在进行推理而不是训练。将图像张量移动到设备上通过模型进行前向传播得到输出。然后应用softmax函数得到概率分布并找到概率最高的类别的索引。 print_res class: {} prob: {:.3}.format(class_indict[str(predict_cla)], predict[predict_cla].numpy()) plt.title(print_res) for i in range(len(predict)): print(class: {:10} prob: {:.3}.format(class_indict[str(i)], predict[i].numpy())) plt.show()
打印出预测结果包括类别名称和对应的概率并在图像上显示这个信息作为标题。然后遍历所有类别的概率并打印出来。最后显示图像。 if __name__ __main__: main()
predict.py
使用PyTorch框架和AlexNet模型进行图像分类的完整示例。
设置设备根据是否检测到CUDA设备GPU设置PyTorch使用CPU或GPU。定义数据转换使用transforms.Compose定义一个转换序列包括调整图像大小到224x224转换为Tensor然后进行归一化。加载图像使用PIL打开指定路径的图像并检查文件是否存在。显示原始图像使用matplotlib显示原始图像。图像预处理应用之前定义的转换序列并增加批量维度以匹配模型输入要求。读取类别索引从JSON文件中加载类别索引映射用于将模型预测的数字标签转换为可读的类别名称。创建模型实例化AlexNet模型设置类别数为5假设有5个类别并将模型移至之前确定的设备CPU或GPU。加载模型权重从指定路径加载训练好的模型权重。模型评估模式设置模型为评估模式关闭dropout和batch normalization的训练特性。进行预测 使用torch.no_grad()上下文管理器关闭梯度计算减少内存消耗加快计算速度。将预处理后的图像传入模型进行预测对输出进行squeeze操作去除多余的维度然后将结果移至CPU。应用softmax函数计算每个类别的预测概率。找到概率最高的类别作为预测结果。显示结果打印并显示预测类别和概率以及所有类别的预测概率。