【放假第13天】神经网络 图片识别

很不错的参考文章
https://blog.csdn.net/weixin_30949361/article/details/94773923

一、定义一个类

from layer_utils import *
import numpy as np
class TwoLayerNet(object):
    #初始化参数,w初始化一般小一点
    def __init__(self,input_dim=3*32*32,hidden_dim=100,num_class=10,
                weight_scale=1e-3,reg=0.0):
        
        self.param={ }
        self.reg=reg
        #w1是连接了一个输入和一个hidden
        '''官方文档中给出的用法是:numpy.random.rand(d0,d1,…dn) 
以给定的形状创建一个数组,并在数组中加入在[0,1]之间均匀分布的随机样本。
官方文档中给出的用法是:numpy.random.rand(d0,d1,…dn) 
以给定的形状创建一个数组,数组元素来符合标准正态分布N(0,1) 
'''
        self.params['W1']=weight_scale*np.random.randn(input_dim,hidden_dim)
        self.params['b1']=np.zeros((1,hidden_dim))
        self.params['W2']=weight_scale*np.random.randn(hidden_dim,num_classes)
        self.params['b2']=np.zeros((1,num_classes))
        
    def loss(self,x,y=None):
        #relu是取w和0的max  每一层都有一个cache,反向传播会直接利用这个
        #正常层一个  relu层一个  两个out
        
        scores=None
        N=X.shape[0]
        #unpack variables from the params dictionary
        W1,b1=self.params['W1'],self.params['b1']
        W2,b3=self.params['W2'],self.params['b2']
        h1,cache1=affine_relu_forward(h1,W1,b1)
        out,cache2=affine_forward(h2,W2,b2)#第二层没有
        scores=out   #最终得到10个类别的得分值
        #softmax  是传进来的得分值  和类别  归一化-概率-loss
        
        if y is None:
            return scores
        
        loss,grads=0,{}
        data_loss,discores=soft_loss(scores,y)#得到softmax反向传播的梯度值
        reg_loss=0.5*self.reg*np.sum(w1*w1)+0.5*self.reg*np.sum(w2*w2)#正则化惩罚项
        loss=data_loss+reg_loss
        #反向传播,算w2和b2
        dh1,dw2,db2=affine_backward(dscores,cache2)
        dx,dw1,db1=affine_rule_backward(dh1,cache1)#两层
        
        #add the regularization gradient distribution
        dw2+=self.reg*w2   #reg是你定义的惩罚的力度 ,加上这个就是一个完整的反向传播
        dw1+=self.reg*w1
        
        grads['W1']=dW1
        grads['b1']=db1
        grads['W2']=dW2
        grads['b2']=db2
        
        return loss grads
        

        

二、图片识别

import matplotlib.pyplot as plt
from fc_net import *
from data_utils import get_CIFAR10_data
# CIFAR10 https://www.cnblogs.com/Jerry-Dong/p/8109938.html
from solver import solver

data=get_CIFAR10_data()
model=TwoLayerNet(reg=0.9)#刚才完成的是这个类
#slover是指定网络的超参数   权重衰减是网络要迭代,学习率是一次走多大,到后面要减小
#batch_size是一次训练多少张   epoches迭代多少轮  每次迭代都逃测试  如果这一组好,取代上一个  每100个批次显示损失并计算的准确度

'''https://www.cnblogs.com/jins-note/p/9520089.html
momentum即动量,它模拟的是物体运动时的惯性,即更新的时候在一定程度上保留之前更新的方向,同时利用当前batch的梯度微调最终的更新方向。这样一来,可以在一定程度上增加稳定性,从而学习地更快,并且还有一定摆脱局部最优的能力: 
Δxt=ρxt−1−ηgt   '''
solver=slover(model,data,
             lr_decay=0.95,print_every=100,num_epochs=40,batch_size=400,
              update_rule='sgd_momentum',
              optim_config={'learning_rate':5e-4,'momentum':0.9}
             )
solver.train()

plt.subplot(2,2,1)
plt.title('Training loss')
plt.plot(solver.loss_history,'o')
plt.xlabel('Iteration')

plt.subplot(2,1,2)
plt.title('Accuracy')
plt.plot(solver.train_acc_history,'-o',label='train')
plt.plot(solver.val_acc_history,'-o',label='val')
plt.plot([0.5]*len(solver.val_acc_history),'k--')
#k--代表以虚线的方式  '-o' --实线圆圈 style='--o' --虚线圆圈
plt.xlabel('Epoch')
plt.legend('loc=lower right')
plt.gcf().set_size_inches(15,12)
'''
当前的图表和子图可以使用plt.gcf()和plt.gca()获得,分别表示Get Current Figure和Get Current Axes。在pyplot模块中,许多函数都是对当前的Figure或Axes对象进行处理,比如说:plt.plot()实际上会通过plt.gca()获得当前的Axes对象ax,然后再调用ax.plot()方法实现真正的绘图。
https://blog.csdn.net/Dontla/article/details/98327176 '''

best_model=model
y_test_pred=np.argmax(best_model.loss(data['x_test'],axis=1))
y_val_pred=np.argmax(best_model.loss(data['x_val'],axis=1))
print("validation set accuracy:",(y_val_pred==data['y_val']).mean())
print("Test set accuracy:",(y_test_pred==data['y_test']).mean())
#

'''看出来过拟合了 train_acc在上上升
val却没有差距还很大  
可能是lr偏大, batchsize小,也只有2层,训练集小
'''


发布了39 篇原创文章 · 获赞 1 · 访问量 457

猜你喜欢

转载自blog.csdn.net/qq_40647378/article/details/103739833