摘自B站一位up的视频,链接:
https://www.bilibili.com/video/BV1ga4y1x7Ld?from=search&seid=4446784377654110608
基础
假如有一张图片,由32×32的颜色点组成,共1024个颜色点
每个颜色点都是单一的一个颜色
所有颜色都由三原色:RGB(红绿蓝)构成,这三种颜色每个都可以取0-255之间的一个数字
例如RGB(255,0,0)表示为红色,RGB(0,0,0)表示为黑色
所以每个颜色点都可以通过一个三位数字的矩阵表示,那么这张图片就可以表示为32×32×3的一个矩阵
所以,做图像识别的第一步就是要把图片转化为32×32×3的矩阵
PS.
-
10000是说一共有10000张图片做测试集
-
reshape()的作用是随机生成一个矩阵的行与列;
-
transpose()简单来说,就相当于数学中的转置,在矩阵中,转置就是把行与列相互调换位置;在三维中,X轴用0表示,Y轴用1表示;Z轴用2来表示;
-
array()是用来产生数组
神经网络
输入是3072,所以X一共是X0-X3071,这些输入都是0-255之间的数字
假设第一层神经网络由11个神经元组成,即图上的Y0-Y10,X与Y之间相连的线上的数字为权重。我们需要把每个X与之相应的权重相乘,再加上一个偏置(一个常数项),就可以得到Y0的输出
【注意:权重和偏置都可以为负】
之后,每一个Y都有一个激活函数,即大于零不变,小于0就为0
经过激活函数之后的Y的输出,会被当作输入喂给下一层的神经网络,即为X0-X10,最后得到十个输出(对应着十个标签),每个输出都要经过一个Softmax函数,转化成0-1之间的概率,代表这张图片被识别为改标签的概率是多少,最后我们选取概率最高的那个标签作为图片的标签
训练模型
用梯度下降不断更新模型中的参数,使损失函数值不断下降
训练第一步,是定义一个损失函数
- 损失函数:指预测结果和正确结果之间的差距有多大。损失函数越大,我们猜测的越不准
- 交叉熵:我们要做的是调整参数把熵的值尽可能地降到最低,使模型更加准确
下面这张图是熵值和每一个参数的关系的一个函数,在第一步中我们的参数是随机生成的,那么可能在函数的左边画×的地方,运用梯度下降的方法往右走一直到最低点
例如:首先往左走一步,发现我们的函数值变大了,所以应该往右走(求L对W在这个点的偏导值,也就是梯度,那就是我们要走的方向)
代码
下面是up分享的代码
import pickle
import os
import numpy as np
# 读取所有文件夹中的pickle文件,分成训练和测试两个部分
def load_data(ROOT):
X, Y = [], []
for i in range(1, 6):
filename = os.path.join(ROOT, 'data_batch_%d' % (i, ))
x, y = load_pickle_file(filename)
X.append(x)
Y.append(y)
X_tr = np.concatenate(X)
Y_tr = np.concatenate(Y)
X_te, Y_te = load_pickle_file(os.path.join(ROOT, 'test_batch'))
return X_tr, Y_tr, X_te, Y_te
# 导入pickle文件, 并将每张图片转换成(10000, 32, 32, 3)的矩阵
def load_pickle_file(filename):
with open(filename, 'rb') as f:
p = pickle.load(f, encoding='latin1')
X = p['data'].reshape(10000, 3, 32, 32).transpose(0, 2, 3, 1).astype('float')
Y = np.array(p['labels'])
return X, Y
X_tr, Y_tr, X_te, Y_te = load_data('./dataset/cifar-10-batches-py')
print(X_tr.shape, Y_tr.shape, X_te.shape, Y_te.shape)
import matplotlib.pyplot as plt
# 展示部分数据集中的图片,每种类型展示7张
classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
num_classes = len(classes)
samples_per_class = 7
for y, cls in enumerate(classes):
idxs = np.flatnonzero(Y_tr == y)
idxs = np.random.choice(idxs, samples_per_class, replace=False)
for i, idx in