最近学习简略钻研了一下python机器学习相干常识,写一个博客也是对本人近期学习的总结吧,内容比拟通俗大佬勿喷
在本教程中,咱们将应用PaddlePaddle框架进行图像分类。咱们将应用CIFAR-10数据集,该数据集蕴含10个不同类别的图像。咱们将通过构建一个卷积神经网络(CNN)模型来对这些图像进行分类。让咱们一步一步地来实现这个工作。
步骤 1:导入所需的包
首先,咱们须要导入所需的包,这些包包含paddle、paddle.fluid、numpy、PIL和matplotlib.pyplot。请确保您曾经装置了这些包,如果没有,请先进行装置。
import paddle as paddleimport paddle.fluid as fluidimport numpy as npfrom PIL import Imageimport matplotlib.pyplot as pltimport os
步骤 2:下载数据集
接下来,咱们须要下载CIFAR-10数据集,以便用于训练和测试。请留神,这段代码在正文块中,因而须要勾销正文能力执行。如果您曾经下载了数据集,能够跳过这一步。
'''!mkdir -p /home/aistudio/.cache/paddle/dataset/cifar/!wget "http://ai-atest.bj.bcebos.com/cifar-10-python.tar.gz" -O cifar-10-python.tar.gz!mv cifar-10-python.tar.gz /home/aistudio/.cache/paddle/dataset/cifar/!ls -a /home/aistudio/.cache/paddle/dataset/cifar/'''
步骤 3:定义数据提供器
咱们须要定义数据提供器来加载训练和测试数据。在这里,咱们应用paddle.batch函数对数据进行批处理,并应用paddle.reader.shuffle函数对训练数据进行随机打乱。
BATCH_SIZE = 128# 用于训练的数据提供器train_reader = paddle.batch( paddle.reader.shuffle(paddle.dataset.cifar.train10(), buf_size=128*100), batch_size=BATCH_SIZE) # 用于测试的数据提供器test_reader = paddle.batch( paddle.dataset.cifar.test10(), batch_size=BATCH_SIZE)
步骤 4:定义卷积神经网络模型
咱们将应用一个卷积神经网络(CNN)模型对图像进行分类。在这个示例中,咱们应用了三个卷积-池化层和一个全连贯层。每个卷积-池化层都应用ReLU激活函数和批归一化(Batch Normalization)。
def convolutional_neural_network(img): # 第一个卷积-池化层 conv_pool_1 = fluid.nets.simple_img_conv_pool( input=img, filter_size=5, num_filters=20, pool_size=2, pool_stride=2, act="relu") conv_pool_1 = fluid.layers.batch_norm(conv_pool_1) # 第二个卷积-池化层 conv_pool_2 = fluid.nets.simple_img_conv_pool( input=conv_pool_1, filter_size=5, num_filters=50, pool_size=2, pool_stride=2, act="relu") conv_pool_2 = fluid.layers.batch_norm(conv_pool_2) # 第三个卷积-池化层 conv_pool_3 = fluid.nets.simple_img_conv_pool( input=conv_pool_2, filter_size=5, num_filters=50, pool_size=2, pool_stride=2, act="relu") # 全连贯层,输入10个类别 prediction = fluid.layers.fc(input=conv_pool_3, size=10, act='softmax') return prediction
步骤 5:定义输出数据和模型预测
咱们须要定义输出数据和模型预测。在这里,咱们应用fluid.layers.data
定义图像数据和标签的输出。而后,咱们调用之前定义的卷积神经网络模型convolutional_neural_network
进行预测。
data_shape = [3, 32, 32]images = fluid.layers.data(name='images', shape=data_shape, dtype='float32')label = fluid.layers.data(name='label', shape=[1], dtype='int64')# 获取分类器,用CNN进行分类predict = convolutional_neural_network(images)
步骤 6:定义损失函数和准确率
咱们定义穿插熵损失函数和准确率来评估模型的性能。穿插熵损失函数用于掂量预测后果与实在标签之间的差别,准确率用于掂量模型在测试数据上的分类准确度。
cost = fluid.layers.cross_entropy(input=predict, label=label)avg_cost = fluid.layers.mean(cost)acc = fluid.layers.accuracy(input=predict, label=label)
步骤 7:定义优化办法
咱们抉择Adam优化器作为优化办法,并将学习率设置为0.001。而后,应用优化器的minimize办法来最小化均匀损失。
optimizer = fluid.optimizer.Adam(learning_rate=0.001)optimizer.minimize(avg_cost)
步骤 8:设置执行环境和参数初始化
依据您的抉择,咱们能够在CPU或GPU上运行代码。依据use_cuda的值,咱们创立一个执行器并初始化参数。
use_cuda = Falseplace = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()exe = fluid.Executor(place)exe.run(fluid.default_startup_program())
步骤 9:训练和测试模型
在此步骤中,咱们开始训练和测试模型。咱们应用一个循环来遍历训练数据集,并计算损失并进行参数更新。在每个epoch完结时,咱们应用测试数据集评估模型的性能。
EPOCH_NUM = 10for epoch in range(EPOCH_NUM): for batch_id, data in enumerate(train_reader()): # 筹备输出数据 image_data = np.array([x[0].reshape(data_shape) for x in data]).astype('float32') label_data = np.array([x[1] for x in data]).astype('int64').reshape(-1, 1) # 运行训练程序 loss, accuracy = exe.run(fluid.default_main_program(), feed={'images': image_data, 'label': label_data}, fetch_list=[avg_cost, acc]) # 每训练100个batch打印一次损失和准确率 if batch_id % 100 == 0: print("Epoch {}, Batch {}, Loss {:.4f}, Accuracy {:.2f}%".format( epoch, batch_id, loss[0], accuracy[0] * 100)) # 在每个epoch完结时进行测试 test_accs = [] test_costs = [] for batch_id, data in enumerate(test_reader()): # 筹备测试数据 image_data = np.array([x[0].reshape(data_shape) for x in data]).astype('float32') label_data = np.array([x[1] for x in data]).astype('int64').reshape(-1, 1) # 运行测试程序 loss, accuracy = exe.run(fluid.default_main_program(), feed={'images': image_data, 'label': label_data}, fetch_list=[avg_cost, acc]) test_accs.append(accuracy[0]) test_costs.append(loss[0]) # 计算均匀测试准确率和损失 test_acc = np.mean(test_accs) test_cost = np.mean(test_costs) print("Epoch {}, Test Loss {:.4f}, Test Accuracy {:.2f}%".format( epoch, test_cost, test_acc * 100))
步骤 10:保留模型
训练完结后,咱们能够将模型保留到磁盘上以供当前应用。
model_save_dir = "./models"if not os.path.exists(model_save_dir): os.makedirs(model_save_dir)fluid.io.save_inference_model(model_save_dir, ['images'], [predict], exe)
至此,咱们实现了应用PaddlePaddle进行图像分类的教程。您能够依据须要对代码进行批改和扩大,以适应不同的利用场景。心愿本教程对您有所帮忙!
残缺代码
# 导入须要的包import paddle as paddleimport paddle.fluid as fluidimport numpy as npfrom PIL import Imageimport matplotlib.pyplot as pltimport os# 数据集下载'''!mkdir -p /home/aistudio/.cache/paddle/dataset/cifar/!wget "http://ai-atest.bj.bcebos.com/cifar-10-python.tar.gz" -O cifar-10-python.tar.gz!mv cifar-10-python.tar.gz /home/aistudio/.cache/paddle/dataset/cifar/!ls -a /home/aistudio/.cache/paddle/dataset/cifar/'''BATCH_SIZE = 128# 用于训练的数据提供器train_reader = paddle.batch( paddle.reader.shuffle(paddle.dataset.cifar.train10(), buf_size=128 * 100), batch_size=BATCH_SIZE)# 用于测试的数据提供器test_reader = paddle.batch( paddle.dataset.cifar.test10(), batch_size=BATCH_SIZE)def convolutional_neural_network(img): # 第一个卷积-池化层 conv_pool_1 = fluid.nets.simple_img_conv_pool( input=img, # 输出图像 filter_size=5, # 滤波器的大小 num_filters=20, # filter 的数量。它与输入的通道雷同 pool_size=2, # 池化核大小2*2 pool_stride=2, # 池化步长 act="relu") # 激活类型 conv_pool_1 = fluid.layers.batch_norm(conv_pool_1) # 第二个卷积-池化层 conv_pool_2 = fluid.nets.simple_img_conv_pool( input=conv_pool_1, filter_size=5, num_filters=50, pool_size=2, pool_stride=2, act="relu") conv_pool_2 = fluid.layers.batch_norm(conv_pool_2) # 第三个卷积-池化层 conv_pool_3 = fluid.nets.simple_img_conv_pool( input=conv_pool_2, filter_size=5, num_filters=50, pool_size=2, pool_stride=2, act="relu") # 以softmax为激活函数的全连贯输入层,10类数据输入10个数字 prediction = fluid.layers.fc(input=conv_pool_3, size=10, act='softmax') return prediction# 定义输出数据data_shape = [3, 32, 32]images = fluid.layers.data(name='images', shape=data_shape, dtype='float32')label = fluid.layers.data(name='label', shape=[1], dtype='int64')# 获取分类器,用cnn进行分类predict = convolutional_neural_network(images)# 获取损失函数和准确率cost = fluid.layers.cross_entropy(input=predict, label=label) # 穿插熵avg_cost = fluid.layers.mean(cost) # 计算cost中所有元素的平均值acc = fluid.layers.accuracy(input=predict, label=label) # 应用输出和标签计算准确率# 获取测试程序test_program = fluid.default_main_program().clone(for_test=True)# 定义优化办法optimizer = fluid.optimizer.Adam(learning_rate=0.001)optimizer.minimize(avg_cost)# 定义应用CPU还是GPU,应用CPU时use_cuda = False,应用GPU时use_cuda = Trueuse_cuda = Falseplace = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()# 创立执行器,初始化参数exe = fluid.Executor(place)exe.run(fluid.default_startup_program())feeder = fluid.DataFeeder(feed_list=[images, label], place=place)all_train_iter = 0all_train_iters = []all_train_costs = []all_train_accs = []def draw_train_process(title, iters, costs, accs, label_cost, lable_acc): plt.title(title, fontsize=24) plt.xlabel("iter", fontsize=20) plt.ylabel("cost/acc", fontsize=20) plt.plot(iters, costs, color='red', label=label_cost) plt.plot(iters, accs, color='green', label=lable_acc) plt.legend() plt.grid() plt.show()EPOCH_NUM = 20model_save_dir = "/home/aistudio/work/catdog.inference.model"for pass_id in range(EPOCH_NUM): # 开始训练 for batch_id, data in enumerate(train_reader()): # 遍历train_reader的迭代器,并为数据加上索引batch_id train_cost, train_acc = exe.run(program=fluid.default_main_program(), # 运行主程序 feed=feeder.feed(data), # 喂入一个batch的数据 fetch_list=[avg_cost, acc]) # fetch均方误差和准确率 all_train_iter = all_train_iter + BATCH_SIZE all_train_iters.append(all_train_iter) all_train_costs.append(train_cost[0]) all_train_accs.append(train_acc[0]) # 每100次batch打印一次训练、进行一次测试 if batch_id % 100 == 0: print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, batch_id, train_cost[0], train_acc[0])) # 开始测试 test_costs = [] # 测试的损失值 test_accs = [] # 测试的准确率 for batch_id, data in enumerate(test_reader()): test_cost, test_acc = exe.run(program=test_program, # 执行测试程序 feed=feeder.feed(data), # 喂入数据 fetch_list=[avg_cost, acc]) # fetch 误差、准确率 test_costs.append(test_cost[0]) # 记录每个batch的误差 test_accs.append(test_acc[0]) # 记录每个batch的准确率 # 求测试后果的平均值 test_cost = (sum(test_costs) / len(test_costs)) # 计算误差平均值(误差和/误差的个数) test_acc = (sum(test_accs) / len(test_accs)) # 计算准确率平均值( 准确率的和/准确率的个数) print('Test:%d, Cost:%0.5f, ACC:%0.5f' % (pass_id, test_cost, test_acc))# 保留模型# 如果保留门路不存在就创立if not os.path.exists(model_save_dir): os.makedirs(model_save_dir)print('save models to %s' % (model_save_dir))fluid.io.save_inference_model(model_save_dir, ['images'], [predict], exe)print('训练模型保留实现!')draw_train_process("training", all_train_iters, all_train_costs, all_train_accs, "trainning cost", "trainning acc")infer_exe = fluid.Executor(place)inference_scope = fluid.core.Scope()def load_image(file): # 关上图片 im = Image.open(file) # 将图片调整为跟训练数据一样的大小 32*32, 设定ANTIALIAS,即抗锯齿.resize是缩放 im = im.resize((32, 32), Image.ANTIALIAS) # 建设图片矩阵 类型为float32 im = np.array(im).astype(np.float32) # 矩阵转置 im = im.transpose((2, 0, 1)) # 将像素值从【0-255】转换为【0-1】 im = im / 255.0 # print(im) im = np.expand_dims(im, axis=0) # 放弃和之前输出image维度统一 print('im_shape的维度:', im.shape) return imwith fluid.scope_guard(inference_scope): # 从指定目录中加载 推理model(inference model) [inference_program, # 预测用的program feed_target_names, # 是一个str列表,它蕴含须要在推理 Program 中提供数据的变量的名称。 fetch_targets] = fluid.io.load_inference_model(model_save_dir, # fetch_targets:是一个 Variable 列表,从中咱们能够失去推断后果。 infer_exe) # infer_exe: 运行 inference model的 executor infer_path = 'dog2.jpg' img = Image.open(infer_path) plt.imshow(img) plt.show() img = load_image(infer_path) results = infer_exe.run(inference_program, # 运行预测程序 feed={feed_target_names[0]: img}, # 喂入要预测的img fetch_list=fetch_targets) # 失去揣测后果 print('results', results) label_list = [ "airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck" ] print("infer results: %s" % label_list[np.argmax(results[0])])