如何编程来识别一只猫(一)

2020年9月22日21:25:16 发表评论

初学神经网络深度学习,让我们做一个简单的模型来识别一张图片是否是猫。

你需要掌握的技能:

  • python基础语法
  • 一点点的神经网络知识

首先建立一个简单的神经网络模型,如下图所示。

如何编程来识别一只猫(一)

如果有一点神经网络知识的话,你大概知道x表示输入,f表示激活函数,y表示输出。并且有以下公式

z  = wT*x+b  #这里表示用线性的常数来预测模型,类似y=kx+b(假如只有一个特征值的话)
y' = f(z)    #使用激活函数,我们就可以得到寻来的y
loss = 定义的loss函数
w -= lr*dw   #其中lr表示学习率,dw表示w的梯度
b -= lr*db   #同上,db表示b的梯度

然后我们就可以开始编程了,我们大概把编程步骤分为以下几步:

1.数据处理

from lr_utils import load_dataset

train_x, train_y, test_x, test_y, classes = load_dataset()#加载数据集
[m, np_x, np_y, chain] = train_x.shape #获得训练集的维度,m是样本个数
imageSize = np_x * np_x * chain #计算图片大小=长*宽*通道(其中3通道为rgb三色)
train_x = train_x.reshape(m, imageSize).T / 255  #除255是为了把它们压缩到[0,1]区间
train_y = train_y.reshape(1, m)#把训练集的y重排为1行m列
test_x = test_x.reshape(test_x.shape[0], imageSize).T / 255
test_y = test_y.reshape(1, test_y.shape[1])

 

2.初始化参数

这里我们要用到的有w,b

# init parameters
def init_parameters(image_size):
    return np.zeros((image_size, 1)), 0

3.梯度下降

# define grad descent function
def grad_descent(w, b, lr, x, y, m):
    a = sigmod(w.T.dot(x) + b)
    dw = x.dot((a - y).T) / m
    w -= lr * dw
    db = np.sum(a - y) / m
    b -= lr * db
    loss = - np.sum(y * np.log(a) + (1 - y) * np.log(1 - a)) / m
    loss = np.squeeze(loss)
    return loss
# optimise the loss
def optimise(w, b, x, learning_rate, y, m, iteration):
    loss = []
    for i in range(iteration):
        loss.append(grad_descent(w, b, learning_rate, x, y, m))
    return loss

4.预测数据

# define predict function
def predict(w, b, x):
    y_hat = sigmod(w.T.dot(x) + b)
    return y_hat

5.用模型分别测试训练集和测试集的准确率

# get accuracy
def get_accuracy(w, b, x, y, m):
    y_hat = predict(w, b, x)
    for i in range(m):
        y_hat[0, i] = 1 if y_hat[0, i] > 0.5 else 0
    accuracy = (1-np.sum(abs(y-y_hat))/m)*100
    return accuracy

6.预测自己图片

from catRecognize import predict
import shelve
import imageio
from skimage.transform import resize

image_size = shelveFile['image_size']
image = imageio.imread('images/timg.jpg')
image = resize(image, output_shape=(np_x, np_x)).reshape((1, image_size)).T
y = predict(w, b, image)
print('this is '+classes[0 if y < 0.5 else 1].decode('utf-8'))

7.运行

  1. 运行main.py就可以训练了并查看训练集和测试集的准确率,还会保存超参数。
  2. 运行guessByModel.py设置你自己的图片就能对图片进行预测了。(必须先运行1)

总结

经过测试,在训练集的准确率最高可达100%,而测试集的正确率可达74%,这还只是用了一个输出层节点,假如设计一个更加复杂的网络,可能准确率会更高。

在测试的时候要不断调节一些参数,如迭代次数,学习率(最重要),才能得到更好的结果。事实上,测试集准确率为74%时,训练集为96%,这已经属于过拟合了,但通过正则化和设计更加复杂的网络可以改善这一状况。

附录

代码我托管在码云上了,有需要的同学可以去那下载,有空的话给个start也好啊。

flyingsheep

发表评论