Соси кошек вместе с кодом! Эта статья участвует【Эссе "Мяу Звезды"】.
Классификация кошек и собак на основе входной сети CNN PaddlePaddle2.x
Классификация изображений заключается в различении различных типов изображений в соответствии с семантической информацией изображения, что является важной базовой проблемой компьютерного зрения.
Классификация кошек и собак - это проблема грубой классификации в классификации изображений.
Сначала импортируйте необходимые пакеты
paddle.fluid ---> Фреймворк глубокого обучения PaddlePaddle
os------------->модуль python, который можно использовать для работы операционной системы
#
# 导入需要的包
import paddle
import numpy as np
from PIL import Image
import sys
from multiprocessing import cpu_count
import matplotlib.pyplot as plt
import os
from paddle.nn import MaxPool2D,Conv2D,BatchNorm2D
from paddle.nn import Linear
print("本教程基于Paddle的版本号为:"+paddle.__version__)
本教程基于Paddle的版本号为:2.0.0
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/__init__.py:107: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import MutableMapping
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/rcsetup.py:20: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Iterable, Mapping
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/colors.py:53: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Sized
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可:
# Also add the following code,
# so that every time the environment (kernel) starts,
# just run the following code:
import sys
sys.path.append('/home/aistudio/external-libraries')
Шаг 1: Подготовьте данные
(1) Введение набора данных
Мы используем набор данных CIFAR10. Набор данных CIFAR10 содержит 60 000 цветных изображений 32x32 в 10 категориях, каждая из которых содержит 6 000 изображений. Среди них 50 000 изображений используются в качестве обучающего набора и 10 000 изображений используются в качестве набора для проверки. На этот раз мы делаем прогнозы только для кошек и собак.
(2) train_reader и test_reader
Пользовательский ридер для обработки обучающих и тестовых наборов
paddle.reader.shuffle() означает, что элементы данных BUF_SIZE каждый раз кэшируются и перемешиваются
paddle.batch() означает, что каждый BATCH_SIZE формирует пакет
#!tar -zxvf /home/aistudio/data/data9154/cifar-10-python.tar.gz
def unpickle(file):
import pickle
with open(file, 'rb') as fo:
dict = pickle.load(fo, encoding='bytes')
return dict
print(unpickle("cifar-10-batches-py/data_batch_1").keys())
print(unpickle("cifar-10-batches-py/test_batch").keys())
dict_keys([b'batch_label', b'labels', b'data', b'filenames'])
dict_keys([b'batch_label', b'labels', b'data', b'filenames'])
def test_mapper(sample):
img, label = sample
#将img数组进行进行归一化处理,得到0到1之间的数值
img= img.flatten().astype('float32')/255.0
return img, label
def train_mapper(sample):
img, label = sample
#将img数组进行进行归一化处理,得到0到1之间的数值
img= img.flatten().astype('float32')/255.0
return img, label
def train_r( buffered_size=1024):
def reader():
xs=[]
ys=[]
for i in range(1,6):
train_dict=unpickle("cifar-10-batches-py/data_batch_%d" % (i,))
xs.append(train_dict[b'data'])
ys.append(train_dict[b'labels'])
Xtr = np.concatenate(xs)
Ytr = np.concatenate(ys)
for (x,y) in zip(Xtr,Ytr):
yield x, int(y)
return (train_mapper, reader,cpu_count(), buffered_size)
def test_r( buffered_size=1024):
def reader():
test_dict=unpickle("cifar-10-batches-py/test_batch")
X=test_dict[b'data']
Y=test_dict[b'labels']
for (x,y) in zip(X,Y):
yield x, int(y)
return paddle.reader.xmap_readers(test_mapper, reader,cpu_count(), buffered_size)
'''
自定义数据集
'''
import paddle
from paddle.io import Dataset
class MyDataset(paddle.io.Dataset):
"""
步骤一:继承paddle.io.Dataset类
"""
def __init__(self, mode='train'):
"""
步骤二:实现构造函数,定义数据集大小
"""
super(MyDataset, self).__init__()
if mode == 'train':
xs=[]
ys=[]
self.data = []
self.label = []
for i in range(1,6):
train_dict=unpickle("cifar-10-batches-py/data_batch_%d" % (i,))
xs.append(train_dict[b'data'])
ys.append(train_dict[b'labels'])
Xtr = np.concatenate(xs)
Ytr = np.concatenate(ys)
for (x,y) in zip(Xtr,Ytr):
x= x.flatten().astype('float32')/255.0
self.data.append(x)
self.label.append(np.array(y).astype('int64'))
else:
self.data = []
self.label = []
test_dict=unpickle("cifar-10-batches-py/test_batch")
X=test_dict[b'data']
Y=test_dict[b'labels']
for (x,y) in zip(X,Y):
x= x.flatten().astype('float32')/255.0
self.data.append(x)
self.label.append(np.array(y).astype('int64'))
def __getitem__(self, index):
"""
步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)
"""
data = self.data[index]
label = self.label[index]
return data, np.array(label, dtype='int64')
def __len__(self):
"""
步骤四:实现__len__方法,返回数据集总数目
"""
return len(self.data)
# 测试定义的数据集
train_dataset = MyDataset(mode='train')
eval_dataset = MyDataset(mode='val')
print('=============train_dataset =============')
print(train_dataset.__getitem__(1)[0].shape,train_dataset.__getitem__(1)[1])
print(train_dataset.__len__())
print('=============eval_dataset =============')
for data, label in eval_dataset:
print(data.shape, label)
break
print(eval_dataset.__len__())
=============train_dataset =============
(3072,) 9
50000
=============eval_dataset =============
(3072,) 3
10000
Шаг 2. Настройка сети
(1) Строительство сети
*** Сетевая модель CNN
В модели CNN сверточная нейронная сеть может лучше использовать структурную информацию изображения. Более простая сверточная нейронная сеть определена ниже. Показана его структура: входное 2D-изображение проходит через кубический сверточный слой, слой пула и Batchnorm, затем полносвязный слой, и, наконец, в качестве выходного слоя используется классификация softmax.
объединениеЭто форма нелинейной субдискретизации, и ее основная функция состоит в том, чтобы уменьшить количество вычислений за счет уменьшения параметров сети и в определенной степени контролировать переоснащение. Обычно объединяющий слой добавляется после сверточного слоя. объединение paddlepaddle по умолчанию равно максимальному объединению. Он делит входной слой на разные области с неперекрывающимися прямоугольными блоками и принимает максимальное значение количества каждого прямоугольного блока в качестве выходных данных.
BatchnormКак следует из названия, норма выполняется для каждого пакета данных одновременно. Функция состоит в том, чтобы сохранить входные данные каждого слоя нейронной сети в одном и том же распределении во время обучения глубокой нейронной сети.
#定义CNN网络
class MyCNN(paddle.nn.Layer):
def __init__(self):
super(MyCNN,self).__init__()
self.conv0 = paddle.nn.Conv2D(in_channels=3, out_channels=20, kernel_size=5, padding=0)
self.pool0 = paddle.nn.MaxPool2D(kernel_size =2, stride =2)
self._batch_norm_0 = paddle.nn.BatchNorm2D(num_features = 20)
self.conv1 = paddle.nn.Conv2D(in_channels=20, out_channels=50, kernel_size=5, padding=0)
self.pool1 = paddle.nn.MaxPool2D(kernel_size =2, stride =2)
self._batch_norm_1 = paddle.nn.BatchNorm2D(num_features = 50)
self.conv2 = paddle.nn.Conv2D(in_channels=50, out_channels=50, kernel_size=5, padding=0)
self.pool2 = paddle.nn.MaxPool2D(kernel_size =2, stride =2)
self.fc1 = paddle.nn.Linear(in_features=50, out_features=10)
def forward(self,input):
input=paddle.reshape(input, shape=[-1, 3,32,32])
x = self.conv0(input)
x = paddle.nn.functional.relu(x)
x = self.pool0(x)
x = self._batch_norm_0(x)
x = self.conv1(x)
x = paddle.nn.functional.relu(x)
x = self.pool1(x)
x = self._batch_norm_1(x)
x = self.conv2(x)
x = paddle.nn.functional.relu(x)
x = self.pool2(x)
x = paddle.reshape(x, [x.shape[0], -1])
x = self.fc1(x)
y = paddle.nn.functional.softmax(x)
return y
Шаг 3. Обучение модели и Шаг 4. Оценка модели
#step3:训练模型
# 用Model封装模型
model = paddle.Model(MyCNN())
model.summary(input_size=(1,3, 32, 32))
---------------------------------------------------------------------------
Layer (type) Input Shape Output Shape Param #
===========================================================================
Conv2D-1 [[1, 3, 32, 32]] [1, 20, 28, 28] 1,520
MaxPool2D-1 [[1, 20, 28, 28]] [1, 20, 14, 14] 0
BatchNorm2D-1 [[1, 20, 14, 14]] [1, 20, 14, 14] 80
Conv2D-2 [[1, 20, 14, 14]] [1, 50, 10, 10] 25,050
MaxPool2D-2 [[1, 50, 10, 10]] [1, 50, 5, 5] 0
BatchNorm2D-2 [[1, 50, 5, 5]] [1, 50, 5, 5] 200
Conv2D-3 [[1, 50, 5, 5]] [1, 50, 1, 1] 62,550
MaxPool2D-3 [[1, 50, 1, 1]] [1, 50, 1, 1] 0
Linear-1 [[1, 50]] [1, 10] 510
===========================================================================
Total params: 89,910
Trainable params: 89,630
Non-trainable params: 280
---------------------------------------------------------------------------
Input size (MB): 0.01
Forward/backward pass size (MB): 0.24
Params size (MB): 0.34
Estimated Total Size (MB): 0.59
---------------------------------------------------------------------------
{'total_params': 89910, 'trainable_params': 89630}
model.prepare(paddle.optimizer.Adam(learning_rate=0.0005, parameters=model.parameters()),
paddle.nn.CrossEntropyLoss(),
paddle.metric.Accuracy())
# 训练可视化VisualDL工具的回调函数
visualdl = paddle.callbacks.VisualDL(log_dir='visualdl_log')
# 启动模型全流程训练
model.fit(train_dataset, epochs=50, batch_size=256, verbose=1)
#保存模型
model.save('model_save_dir')
The loss value printed in the log is the current step, and the metric is the average value of previous step.
Epoch 1/50
step 20/196 [==>...........................] - loss: 2.1580 - acc: 0.2246 - ETA: 3s - 18ms/st
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/layers/utils.py:77: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
return (isinstance(seq, collections.Sequence) and
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/nn/layer/norm.py:636: UserWarning: When training, we now always track global mean and variance.
"When training, we now always track global mean and variance.")
step 40/196 [=====>........................] - loss: 2.1560 - acc: 0.2699 - ETA: 1s - 13ms/stepstep 196/196 [==============================] - loss: 1.9848 - acc: 0.4067 - 9ms/step
Epoch 2/50
step 196/196 [==============================] - loss: 1.8542 - acc: 0.5571 - 8ms/step
Epoch 3/50
step 196/196 [==============================] - loss: 1.9660 - acc: 0.6163 - 8ms/step
Epoch 4/50
step 196/196 [==============================] - loss: 1.8622 - acc: 0.6516 - 9ms/step
Epoch 5/50
step 196/196 [==============================] - loss: 1.7989 - acc: 0.6803 - 7ms/step
Epoch 6/50
step 196/196 [==============================] - loss: 1.7298 - acc: 0.7024 - 8ms/step
Epoch 7/50
step 196/196 [==============================] - loss: 1.7754 - acc: 0.7196 - 8ms/step
Epoch 8/50
step 196/196 [==============================] - loss: 1.6815 - acc: 0.7379 - 8ms/step
Epoch 9/50
step 196/196 [==============================] - loss: 1.8101 - acc: 0.7509 - 8ms/step
Epoch 10/50
step 196/196 [==============================] - loss: 1.6813 - acc: 0.7647 - 7ms/step
Epoch 11/50
step 196/196 [==============================] - loss: 1.6892 - acc: 0.7755 - 8ms/step
Epoch 12/50
step 196/196 [==============================] - loss: 1.7464 - acc: 0.7867 - 8ms/step
Epoch 13/50
step 196/196 [==============================] - loss: 1.6684 - acc: 0.7973 - 8ms/step
Epoch 14/50
step 196/196 [==============================] - loss: 1.6570 - acc: 0.8043 - 8ms/step
Epoch 15/50
step 196/196 [==============================] - loss: 1.7619 - acc: 0.8107 - 8ms/step
Epoch 16/50
step 196/196 [==============================] - loss: 1.6384 - acc: 0.8200 - 8ms/step
Epoch 17/50
step 196/196 [==============================] - loss: 1.6496 - acc: 0.8268 - 9ms/step
Epoch 18/50
step 196/196 [==============================] - loss: 1.5964 - acc: 0.8312 - 11ms/step
Epoch 19/50
step 196/196 [==============================] - loss: 1.6590 - acc: 0.8370 - 10ms/step
Epoch 20/50
step 196/196 [==============================] - loss: 1.6211 - acc: 0.8415 - 10ms/step
Epoch 21/50
step 196/196 [==============================] - loss: 1.6676 - acc: 0.8439 - 9ms/step
Epoch 22/50
step 196/196 [==============================] - loss: 1.6594 - acc: 0.8490 - 10ms/step
Epoch 23/50
step 196/196 [==============================] - loss: 1.5433 - acc: 0.8521 - 10ms/step
Epoch 24/50
step 196/196 [==============================] - loss: 1.5985 - acc: 0.8551 - 10ms/step
Epoch 25/50
step 196/196 [==============================] - loss: 1.5646 - acc: 0.8580 - 10ms/step
Epoch 26/50
step 196/196 [==============================] - loss: 1.5897 - acc: 0.8608 - 10ms/step
Epoch 27/50
step 196/196 [==============================] - loss: 1.5450 - acc: 0.8625 - 10ms/step
Epoch 28/50
step 196/196 [==============================] - loss: 1.5929 - acc: 0.8646 - 8ms/step
Epoch 29/50
step 196/196 [==============================] - loss: 1.6742 - acc: 0.8669 - 9ms/step
Epoch 30/50
step 196/196 [==============================] - loss: 1.5607 - acc: 0.8684 - 9ms/step
Epoch 31/50
step 196/196 [==============================] - loss: 1.6057 - acc: 0.8709 - 11ms/step
Epoch 32/50
step 196/196 [==============================] - loss: 1.6948 - acc: 0.8716 - 10ms/step
Epoch 33/50
step 196/196 [==============================] - loss: 1.5785 - acc: 0.8732 - 9ms/step
Epoch 34/50
step 196/196 [==============================] - loss: 1.5547 - acc: 0.8751 - 8ms/step
Epoch 35/50
step 196/196 [==============================] - loss: 1.5902 - acc: 0.8768 - 8ms/step
Epoch 36/50
step 196/196 [==============================] - loss: 1.5661 - acc: 0.8787 - 8ms/step
Epoch 37/50
step 196/196 [==============================] - loss: 1.6124 - acc: 0.8780 - 9ms/step
Epoch 38/50
step 196/196 [==============================] - loss: 1.6125 - acc: 0.8801 - 10ms/step
Epoch 39/50
step 196/196 [==============================] - loss: 1.6456 - acc: 0.8791 - 9ms/step
Epoch 40/50
step 196/196 [==============================] - loss: 1.6018 - acc: 0.8816 - 10ms/step
Epoch 41/50
step 196/196 [==============================] - loss: 1.6161 - acc: 0.8837 - 9ms/step
Epoch 42/50
step 196/196 [==============================] - loss: 1.5863 - acc: 0.8841 - 8ms/step
Epoch 43/50
step 196/196 [==============================] - loss: 1.6033 - acc: 0.8847 - 8ms/step
Epoch 44/50
step 196/196 [==============================] - loss: 1.5980 - acc: 0.8858 - 8ms/step
Epoch 45/50
step 196/196 [==============================] - loss: 1.5921 - acc: 0.8851 - 10ms/step
Epoch 46/50
step 196/196 [==============================] - loss: 1.5371 - acc: 0.8866 - 10ms/step
Epoch 47/50
step 196/196 [==============================] - loss: 1.5950 - acc: 0.8879 - 8ms/step
Epoch 48/50
step 196/196 [==============================] - loss: 1.5795 - acc: 0.8870 - 8ms/step
Epoch 49/50
step 196/196 [==============================] - loss: 1.5749 - acc: 0.8880 - 7ms/step
Epoch 50/50
step 196/196 [==============================] - loss: 1.5721 - acc: 0.8894 - 8ms/step
Потрясающе, 1.000 акк за 10 раундов
Хранение моделей
Сохраните нашу обученную модель для последующей оценки и тестирования.
model.save('sheep_model')
Оценка и тестирование модели
тест предсказания партии
оценивать
После оценки показатель точности составляет 0,8867924528301887, и все.
# plot the evaluate
model.evaluate(eval_dataset,verbose=1)
Eval begin...
The loss value printed in the log is the current batch, and the metric is the average value of previous step.
step 10000/10000 [==============================] - loss: 1.4612 - acc: 0.6668 - 3ms/step
Eval samples: 10000
{'loss': [1.4611502], 'acc': 0.6668}
предсказывать
Делайте прогнозы по данным eval_dataset
print('测试数据集样本量:{}'.format(len(eval_dataset)))
测试数据集样本量:10000
# 执行预测
result = model.predict(eval_dataset)
Predict begin...
step 10000/10000 [==============================] - 3ms/step
Predict samples: 10000
# 打印前10条看看结果
for idx in range(10):
predict_label = str(np.argmax(result[0][idx]))
real_label = str(eval_dataset.__getitem__(idx)[1])
print('样本ID:{}, 真实标签:{}, 预测值:{}'.format(idx, real_label, predict_label))
样本ID:0, 真实标签:3, 预测值:9
样本ID:1, 真实标签:8, 预测值:8
样本ID:2, 真实标签:8, 预测值:8
样本ID:3, 真实标签:0, 预测值:0
样本ID:4, 真实标签:6, 预测值:4
样本ID:5, 真实标签:6, 预测值:6
样本ID:6, 真实标签:1, 预测值:1
样本ID:7, 真实标签:6, 预测值:6
样本ID:8, 真实标签:3, 预测值:3
样本ID:9, 真实标签:1, 预测值:1