栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Python

吴恩达作业(4)tensorflow搭建三层神经网络以及应用--识别手势

Python 更新时间:发布时间: 百科书网 趣学号

题目:
输入手势图片,判断手势数字。如:

输出数字 5 5 5

数据集:

  1. test_signs.h5:
    训练集,维度为:(1080,64,64,3),即1080张64*64的彩色图片
  2. train_signs.h5:
    测试集,维度为:(120,64,64,3),即120张64*64的彩色图片

参考博客

加载数据集
#加载和处理数据
def load_data():
    #获取原始训练集数据
    train_data_org = h5py.File('train_signs.h5')
    test_data_org = h5py.File('test_signs.h5')
    
    #h5文件类似字典类型,通过key去获取value
    for key in train_data_org.keys():
        print(key)
    '''
    输出:
    list_classes
    train_set_x
    train_set_y
    '''
    
    #获取训练集数据
    train_x_org = train_data_org["train_set_x"]
    train_y_org = train_data_org["train_set_y"]
    
    #获取测试集数据
    test_x_org = test_data_org["test_set_x"]
    test_y_org = test_data_org["test_set_y"]
    
    #维度和样本数量
    #feature维度
    n = np.shape(train_x_org)[1]*np.shape(train_x_org)[2]*np.shape(train_x_org)[3]
    #训练集样本数
    m_train = np.shape(train_x_org)[0]
    #测试集样本数
    m_test = np.shape(test_x_org)[0]
    
    #将标签平坦成一维数组
    train_y = np.array(train_y_org).reshape(1,m_train)
    test_y = np.array(test_y_org).reshape(1,m_test)
    
    #x数据集是64x*64*3*m的图片数组,将数据集转成12288*m的图片数组
    train_x = np.array(train_x_org).reshape(m_train,-1).T
    #reshape(n,m_train)
    test_x = np.array(test_x_org).reshape(m_test, -1).T
    #reshape(n,m_test)
    
    return train_x_org,test_x_org,train_x,test_x,train_y,test_y
基本函数定义

为x和y创建占位符:

为传入的数据参数 t r a i n _ x , t e s t _ x , t r a i n _ y , t e s t _ y train_x,test_x,train_y,test_y train_x,test_x,train_y,test_y创建占位符placeholder,为需要梯度下降的参数创建变量 V a r i a b l e Variable Variable

'''
n_x:输入数据的维度,即feature数
n_y:输出数据的维度,即C
'''
def create_placeholders(n_x,n_y):
    x = tf.compat.v1.placeholder(tf.float32,[n_x,None],name='x')
    y = tf.compat.v1.placeholder(tf.float32,[n_y,None],name='y')
    return x,y

将标签集转换成one-hot编码

def convert_to_one_hot(Y, C):
    Y = np.eye(C)[Y.reshape(-1)].T
    return Y
参数初始化

这里创建的是[12288,25,12,6]的三层神经网络
x − > R e L U − > R e L U − > s o f t m a x − > y x->ReLU->ReLU->softmax->y x−>ReLU−>ReLU−>softmax−>y

def init_parameters():
    #设置随机数种子
    tf.random.set_seed(1)
    #采用he初始化
    initializer = tf.keras.initializers.glorot_normal()
    #定义变量,权重和偏置  神经网络结构:[12288,25,12,6]
    w1 = tf.Variable(initializer([25,12288]))
    b1 = tf.Variable(initializer([25,1]))
    w2 = tf.Variable(initializer([12,25]))
    b2 = tf.Variable(initializer([12,1]))
    w3 = tf.Variable(initializer([6,12]))
    b3 = tf.Variable(initializer([6,1]))
    
    parameters = {'w1':w1,
                  'b1':b1,
                  'w2':w2,
                  'b2':b2,
                  'w3':w3,
                  'b3':b3
                 }
    return parameters
前向传播
'''
x:输入数据
parameters:权重w和偏置b
'''
def forward_propagation(x,parameters):
    w1 = parameters['w1']
    b1 = parameters['b1']
    w2 = parameters['w2']
    b2 = parameters['b2']
    w3 = parameters['w3']
    b3 = parameters['b3']
    
    z1 = tf.matmul(w1,x)+b1
    a1 = tf.nn.relu(z1)
    
    z2 = tf.matmul(w2,a1)+b2
    a2 = tf.nn.relu(z2)
    
    #把z3作为损失函数的输入,不需要a3【TensorFlow中最后的线性输出层的输出作为计算损失函数的输入】
    z3 = tf.matmul(w3,a2)+b3
    
    return z3
代价函数
def costfunction(z3,y):
    #转置
    z3 = tf.transpose(z3)
    y = tf.transpose(y)
    
    
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=z3,labels=y))
    
    return cost
小批量梯度下降数据集划分
'''
小批量梯度下降
'''
def mini_batch(x,y,mini_batch_size):
    np.random.seed(0)
    #样本数
    m = x.shape[1]
    
    mini_batches = []
    
    #获取打乱的下标,打乱x和y
    index = np.array(np.random.permutation(m))
    shuffled_x = x[:,index]
    shuffled_y = y[:,index]
    
    #分割数据集
    mini_batch_num = m//mini_batch_size
    for k in range(mini_batch_num):
        x_ = shuffled_x[:,k*mini_batch_size:(k+1)*mini_batch_size]
        y_ = shuffled_y[:,k*mini_batch_size:(k+1)*mini_batch_size]
        
        #加入到列表中
        mini_batches.append([x_,y_])
    
    #若不能等分,还有剩余的
    if m%mini_batch_size !=0:
        x_ = shuffled_x[:,mini_batch_num*mini_batch_size:]
        y_ = shuffled_y[:,mini_batch_num*mini_batch_size:]
        
        mini_batches.append([x_,y_])
    
    return mini_batches
反向传播

使用tensorflow的优化器来进行反向传播和梯度下降

#最小化代价函数,即找到合适的Variable最小化代价函数
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
#执行优化器,即执行一次反向反向传播和梯度下降;使用_来接收不想要的值
_,mini_batch_cost = sess.run([optimizer,cost],feed_dict={x:mini_x,y:mini_y})
模型整合
def nn(X_train,Y_train,X_test,Y_test,learning_rate=0.001,epochs=1500,mini_batch_size=32):
    
    n_x,m = X_train.shape
    n_y = Y_train.shape[0]
    
    costs = []
    
    #创建占位符
    x,y = create_placeholders(n_x,n_y)
    
    #初始化参数
    parameters = init_parameters()
    
    #前向传播
    z3 = forward_propagation(x,parameters)
    
    #
    cost = costfunction(z3,y)
    
    #反向传播
    optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
    
    #初始化所有变量
    inti = tf.compat.v1.global_variables_initializer()
    #创建会话
    sess = tf.compat.v1.Session()
    
    with tf.compat.v1.Session() as sess:
        sess.run(inti)

        for epoch in range(epochs):
        		#每次mini_batch的代价函数值
            epoch_cost = 0
					#可以划分多少个mini_batc
            mini_batch_num = m//mini_batch_size
					#划分mini_batch
            mini_batchs = mini_batch(X_train,Y_train,mini_batch_size)
					#对每个mini_batch进行反向传播和梯度下降
            for mini in mini_batchs:
                [mini_x,mini_y] = mini

                _,mini_batch_cost = sess.run([optimizer,cost],feed_dict={x:mini_x,y:mini_y})
						#相当于把每个mini_btach的代价函数值相加再除于mini_btach的数量,就是在算平均值
                epoch_cost = epoch_cost + mini_batch_cost/mini_batch_num

            if epoch%5 == 0:
                costs.append(epoch_cost)
                if epoch%100 == 0:
                    print("epoch = "+str(epoch)+"  epoch_cost = "+str(epoch_cost))
        plt.plot(costs)
        plt.ylabel('cost')
        plt.xlabel('epoch')
        plt.show()

        #保存参数到seseeion
        parameters = sess.run(parameters)

        #获取预测正确的样本下标,argmax函数找到最大值所在的下标
        correct_prediction = tf.equal(tf.argmax(z3),tf.argmax(y))

#正确率
        accuracy = tf.compat.v1.reduce_mean(tf.cast(correct_prediction,"float"))
		#accuracy.eval(feed_dict,Session)评估一个值,即进行计算;
        print("训练集的准确率:", accuracy.eval({x: X_train, y: Y_train}))
        print("测试集的准确率:", accuracy.eval({x: X_test, y: Y_test}))
    
    return parameters
加载数据与数据处理

x x x归一化和 y y y转成one-hot编码

train_x_org,test_x_org,train_x,test_x,train_y,test_y = load_data()
#plt.imshow(train_x_org[6])

#归一化
train_x,test_x = train_x/255,test_x/255
train_y,test_y = convert_to_one_hot(train_y,6),convert_to_one_hot(test_y,6)
print('原始训练集数据维度:',train_x_org.shape)
print('训练集数据维度:',train_x.shape)
执行模型
start_time = time.perf_counter()
parameters = nn(train_x,train_y,test_x,test_y,learning_rate=0.0001,epochs=1500,mini_batch_size=32)
end_time = time.perf_counter()
print("CPU的执行时间 = " + str(end_time - start_time) + " 秒" )
执行结果
list_classes
train_set_x
train_set_y
原始训练集数据维度: (1080, 64, 64, 3)
训练集数据维度: (12288, 1080)
epoch = 0  epoch_cost = 1.8585812756509497
epoch = 100  epoch_cost = 0.7151738224607526
epoch = 200  epoch_cost = 0.40799333019690076
epoch = 300  epoch_cost = 0.25242444647080975
epoch = 400  epoch_cost = 0.1505744911052964
epoch = 500  epoch_cost = 0.094912569292567
epoch = 600  epoch_cost = 0.10143834719377935
epoch = 700  epoch_cost = 0.05500200864943591
epoch = 800  epoch_cost = 0.030319687966821773
epoch = 900  epoch_cost = 0.016815169530948908
epoch = 1000  epoch_cost = 0.0380156317330671
epoch = 1100  epoch_cost = 0.008082679885608906
epoch = 1200  epoch_cost = 0.0040393410758538684
epoch = 1300  epoch_cost = 0.0025025757689339416
epoch = 1400  epoch_cost = 0.0013717231517093198

训练集的准确率: 1.0
测试集的准确率: 0.8333333
CPU的执行时间 = 264.22956630000044 秒
函数预测
#其实就是跑一下前向传播和选择最大值所在下标
def predict(X,parameters):
    
    x = tf.compat.v1.placeholder("float", [12288, 1])
    
    z3 = forward_propagation(x, parameters)
    p = tf.argmax(z3)
    
    sess = tf.compat.v1.Session()
    prediction = sess.run(p, feed_dict = {x: X})
        
    return prediction
总结
  • 为传入的数据参数 t r a i n _ x , t e s t _ x , t r a i n _ y , t e s t _ y train_x,test_x,train_y,test_y train_x,test_x,train_y,test_y创建占位符placeholder,为需要梯度下降的参数创建变量 V a r i a b l e Variable Variable
  • TensorFlow中最后的线性输出层的输出作为计算损失函数的输入
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/1033664.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号