python+tensorflow对mnist数据集的神经网络训练和推理 加参数提取(图片、权重、偏置)----简易版

一、数据集的获取

from tensorflow_core.examples.tutorials.mnist import input_data
from scipy import misc
import numpy as np
import os


#获取数据集

mnist = input_data.read_data_sets("mnist_data/",one_hot=True)
#创建train的文件夹 存放训练图片
if not os.path.exists("train"):
    os.mkdir("train")
#创建test的文件夹 存放测试图片
if not os.path.exists("test"):
    os.mkdir("test")
for(idx,img) in enumerate(mnist.train.images):
    img_arr = np.reshape(img,[28,28])
    misc.imsave("train/train_"+str(idx)+".bmp",img_arr)    
for(idx,img) in enumerate(mnist.test.images):
    img_arr = np.reshape(img,[28,28])
    misc.imsave("test/test_"+str(idx)+".bmp",img_arr)


就会得到训练图片和测试图片,主要选择测试集中0-9各一张图片用于图片参数提取

二、python+tensoflow的训练

import tensorflow as tf
from tensorflow_core.examples.tutorials.mnist import input_data 


Neure_Num = 64
#下载MNIST手写数字集,将手写数字集28*28图像变成1维的784个数据
mnist = input_data.read_data_sets("mnist_data/",one_hot=True)

#输入和输出   tf.placeholder 提前占位
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])

#正向传播

#layer1
#输入28x28的图片,64个神经元,激活函数relu,64个
#定义权重张量w1,偏置张量b1,784个输入层神经元连接64个隐藏层神经元
w1 = tf.Variable(tf.truncated_normal([784,Neure_Num]),dtype = tf.float32)
b1 = tf.Variable(tf.zeros([1,Neure_Num]),dtype = tf.float32)
#定义隐藏层输出张量a,使用tf.nn.relu激活函数,tf.matmul(x,w1)+b1表示神经元的连接
z1 = tf.matmul(x,w1) + b1
a = tf.nn.relu(z1)

#layer2
#第一层的输出为64,所以第二层输入64个数据的一维张量,
#10个神经元,经过softmax,输出
#使用变量做参数,数据位浮点型,
w2 = tf.Variable(tf.ones([Neure_Num,10]),dtype = tf.float32)
b2 = tf.Variable(tf.zeros([1,10]),dtype = tf.float32)
z2 = tf.matmul(a,w2) + b2
y_ = tf.nn.softmax(z2)

#实现反向传播
#计算损失函数  使用的是交叉熵损失函数
loss = tf.reduce_mean(-tf.reduce_sum(y*tf.log(y_),axis = 1))
#选择合适的优化器
train_step = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(loss)
#至此计算图构建完成

#初始化变量张量
init = tf.global_variables_initializer()
sess = tf.Session()  #打开会话
sess.run(init)

#每训练一个批次样本数据后后获得识别正确率

correct_prediction = tf.equal(tf.argmax(y_,axis = 1),tf.argmax(y, axis = 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

#定义好上面所有的运行方式后,使用sess.run启动tensorflow
#在1000轮训练中,mnist.train.next_batch(100)表示每轮训练取出100张样本图片,
#用feed_dict方法把100张样本图片扔进占位符x,y进行训练,train_step参数是上面定义好的网络权重和偏置的调整方法
#每训练100轮就检验一次MNIST手写数据集中的10000张测试图片

for i in range(10000):
    batch_xs,batch_ys = mnist.train.next_batch(100)
    #启动训练
    sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
    if(i % 1000 ==0):
        print("loss:",sess.run(loss,feed_dict={x:mnist.test.images,y:mnist.test.labels}))
        print("accuracy:",sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}))

三、预测predict

import tensorflow as tf
from tensorflow_core.examples.tutorials.mnist import input_data 
from scipy import misc
import numpy as np
from PIL import Image
from itertools import chain

Neure_Num = 64
#下载MNIST手写数字集,将手写数字集28*28图像变成1维的784个数据
mnist = input_data.read_data_sets("mnist_data/",one_hot=True)

#输入和输出   tf.placeholder 提前占位
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])

#正向传播

#layer1
#输入28x28的图片,64个神经元,激活函数relu,64个
#定义权重张量w1,偏置张量b1,784个输入层神经元连接64个隐藏层神经元
w1 = tf.Variable(tf.truncated_normal([784,Neure_Num]),dtype = tf.float32)
b1 = tf.Variable(tf.zeros([1,Neure_Num]),dtype = tf.float32)
#定义隐藏层输出张量a,使用tf.nn.relu激活函数,tf.matmul(x,w1)+b1表示神经元的连接
z1 = tf.matmul(x,w1) + b1
a = tf.nn.relu(z1)

#layer2
#第一层的输出为64,所以第二层输入64个数据的一维张量,
#10个神经元,经过softmax,输出
#使用变量做参数,数据位浮点型,
w2 = tf.Variable(tf.ones([Neure_Num,10]),dtype = tf.float32)
b2 = tf.Variable(tf.zeros([1,10]),dtype = tf.float32)
z2 = tf.matmul(a,w2) + b2
y_ = tf.nn.softmax(z2)

#实现反向传播
#计算损失函数  使用的是交叉熵损失函数
loss = tf.reduce_mean(-tf.reduce_sum(y*tf.log(y_),axis = 1))
#选择合适的优化器
train_step = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(loss)
#至此计算图构建完成

#初始化变量张量
init = tf.global_variables_initializer()
sess = tf.Session()  #打开会话
sess.run(init)

#每训练一个批次样本数据后后获得识别正确率

correct_prediction = tf.equal(tf.argmax(y_,axis = 1),tf.argmax(y, axis = 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

#定义好上面所有的运行方式后,使用sess.run启动tensorflow
#在1000轮训练中,mnist.train.next_batch(100)表示每轮训练取出100张样本图片,
#用feed_dict方法把100张样本图片扔进占位符x,y进行训练,train_step参数是上面定义好的网络权重和偏置的调整方法
#每训练100轮就检验一次MNIST手写数据集中的10000张测试图片

for i in range(10000):
    batch_xs,batch_ys = mnist.train.next_batch(100)
    #启动训练
    sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
    if(i % 1000 ==0):
        print("loss:",sess.run(loss,feed_dict={x:mnist.test.images,y:mnist.test.labels}))
        print("accuracy:",sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}))

#先导入图片
# 1、打开文件
# 2、转换为数组
# 3、转换为浮点型
# 4、转换列表
# 5、转换为张量
#读取0~9其中一张图片进行测试
test_img = Image.open("pic_4.bmp")
#将图片数据转化为数组
test_img_array =  np.array(test_img)     
# 转换为浮点型
test_img_array = np.asarray(test_img_array,dtype='float32')
#转换列表  转化成一阶张量
test_img_array = list(chain.from_iterable(test_img_array))
#转化为二阶张量
test_img_array = [test_img_array]
print(test_img_array)

#predice   需要打开会话  因为之前已经打开了  这里就不需要打开
layer1 = tf.nn.relu(tf.matmul(test_img_array,w1) + b1)
predict =  tf.nn.softmax(tf.matmul(layer1,w2) + b2)
print("predict result:",sess.run(predict))

在这里插入图片描述
输入的是图片4,预测结果一致

四、参数提取成 c头文件的形式(例:input_0.h)

目的:为了实现用C 语言推理

①权重和偏置的提取

import tensorflow as tf
from tensorflow_core.examples.tutorials.mnist import input_data 
from scipy import misc
import numpy as np
from PIL import Image
from itertools import chain

Neure_Num = 64
#下载MNIST手写数字集,将手写数字集28*28图像变成1维的784个数据
mnist = input_data.read_data_sets("mnist_data/",one_hot=True)

#输入和输出   tf.placeholder 提前占位
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])

#正向传播

#layer1
#输入28x28的图片,64个神经元,激活函数relu,64个
#定义权重张量w1,偏置张量b1,784个输入层神经元连接64个隐藏层神经元
w1 = tf.Variable(tf.truncated_normal([784,Neure_Num]),dtype = tf.float32)
b1 = tf.Variable(tf.zeros([1,Neure_Num]),dtype = tf.float32)
#定义隐藏层输出张量a,使用tf.nn.relu激活函数,tf.matmul(x,w1)+b1表示神经元的连接
z1 = tf.matmul(x,w1) + b1
a = tf.nn.relu(z1)

#layer2
#第一层的输出为64,所以第二层输入64个数据的一维张量,
#10个神经元,经过softmax,输出
#使用变量做参数,数据位浮点型,
w2 = tf.Variable(tf.ones([Neure_Num,10]),dtype = tf.float32)
b2 = tf.Variable(tf.zeros([1,10]),dtype = tf.float32)
z2 = tf.matmul(a,w2) + b2
y_ = tf.nn.softmax(z2)

#实现反向传播
#计算损失函数  使用的是交叉熵损失函数
loss = tf.reduce_mean(-tf.reduce_sum(y*tf.log(y_),axis = 1))
#选择合适的优化器
train_step = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(loss)
#至此计算图构建完成

#初始化变量张量
init = tf.global_variables_initializer()
sess = tf.Session()  #打开会话
sess.run(init)

#每训练一个批次样本数据后后获得识别正确率

correct_prediction = tf.equal(tf.argmax(y_,axis = 1),tf.argmax(y, axis = 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

#定义好上面所有的运行方式后,使用sess.run启动tensorflow
#在1000轮训练中,mnist.train.next_batch(100)表示每轮训练取出100张样本图片,
#用feed_dict方法把100张样本图片扔进占位符x,y进行训练,train_step参数是上面定义好的网络权重和偏置的调整方法
#每训练100轮就检验一次MNIST手写数据集中的10000张测试图片

for i in range(10000):
    batch_xs,batch_ys = mnist.train.next_batch(100)
    #启动训练
    sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
    if(i % 1000 ==0):
        print("loss:",sess.run(loss,feed_dict={x:mnist.test.images,y:mnist.test.labels}))
        print("accuracy:",sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels}))

#先导入图片
# 1、打开文件
# 2、转换为数组
# 3、转换为浮点型
# 4、转换列表
# 5、转换为张量
#读取0~9其中一张图片进行测试
test_img = Image.open("pic_4.bmp")
#将图片数据转化为数组
test_img_array =  np.array(test_img)     
# 转换为浮点型
test_img_array = np.asarray(test_img_array,dtype='float32')
#转换列表  转化成一阶张量
test_img_array = list(chain.from_iterable(test_img_array))
#转化为二阶张量
test_img_array = [test_img_array]
print(test_img_array)

#predice   需要打开会话  因为之前已经打开了  这里就不需要打开
layer1 = tf.nn.relu(tf.matmul(test_img_array,w1) + b1)
predict =  tf.nn.softmax(tf.matmul(layer1,w2) + b2)
print("predict result:",sess.run(predict))

# #参数提取
# with open("input_4.h",'w') as f:
#     new_str1 = str(test_img_array)
#     new_str2 = new_str1.replace('[','')
#     new_str3 = new_str2.replace(']','')
#     f.write("float input_4[784]={"+new_str3+"};\n") 
#     print("图片参数读取完成")
#     f.close()

#通过.eval函数可以把tensor转化为numpy类数据
#print(type(w1_value))
#transpose()函数的作用就是调换数组的行列值的索引值,类似于求矩阵的转置:
#tolist()将数组或者矩阵转换成列表
#str()将列表数据转化为字符串
#replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次

with open("layer1_weight.h",'w') as f:
    w1_numpy = w1.eval(session=sess)
    print(type(w1_numpy))
    print(w1_numpy)
    print(w1_numpy.shape)
    # new_str1 = str(np.transpose(w1_numpy).tolist())
    new_str1 = str(w1_numpy.tolist())
    new_str2 = new_str1.replace('[','')
    new_str3 = new_str2.replace(']','')
    f.write("float layer1_weight["+str(784*64)+"]={"+new_str3+"};\n")
    print("第一层的权重保存成功")
    f.close()

with open("layer1_bais.h",'w') as f:
    b1_numpy = b1.eval(session=sess)
    print(type(b1_numpy))
    # new_str1 = str(np.transpose(b1_numpy).tolist())
    new_str1 = str(b1_numpy.tolist())
    new_str2 = new_str1.replace('[','')
    new_str3 = new_str2.replace(']','')
    f.write("float layer1_bais["+str(64)+"]={"+new_str3+"};\n")
    print("第一层的偏置保存成功")
    f.close()

print("第一层的参数保存完毕")


with open("layer2_weight.h",'w') as f:
    w2_numpy = w2.eval(session=sess)
    print(type(w2_numpy))
    # new_str1 = str(np.transpose(w2_numpy).tolist())
    new_str1 = str(w2_numpy.tolist())
    new_str2 = new_str1.replace('[','')
    new_str3 = new_str2.replace(']','')
    f.write("float layer2_weight["+str(10*64)+"]={"+new_str3+"};\n")
    print("第二层的权重保存成功")
    f.close()

with open("layer2_bais.h",'w') as f:
    b2_numpy = b2.eval(session=sess)
    print(type(b2_numpy))
    # new_str1 = str(np.transpose(b2_numpy).tolist())
    new_str1 = str(b2_numpy.tolist())
    new_str2 = new_str1.replace('[','')
    new_str3 = new_str2.replace(']','')
    f.write("float layer2_bais["+str(10)+"]={"+new_str3+"};\n")
    print("第二层的偏置保存成功")
    f.close()

print("第二层的参数保存完毕")

在这里插入图片描述
生成的头文件如下:
在这里插入图片描述

②图片参数保存

from PIL import Image
from itertools import chain
import numpy as np
#先导入图片
# 1、打开文件
# 2、转换为数组
# 3、转换为浮点型
# 4、转换列表
# 5、转换为张量
#读取0~9其中一张图片进行测试

pic_name = ["pic_0.bmp",
            "pic_1.bmp",
            "pic_2.bmp",
            "pic_3.bmp",
            "pic_4.bmp",
            "pic_5.bmp",
            "pic_6.bmp",
            "pic_7.bmp",
            "pic_8.bmp",
            "pic_9.bmp"]

save_pic_name = [
            "input_0",    
            "input_1",
            "input_2",
            "input_3",
            "input_4",
            "input_5",
            "input_6",
            "input_7",
            "input_8",
            "input_9"
            ]

# print(pic_name[1])
for i in range (10):
    test_img = Image.open(pic_name[i])
    #将图片数据转化为数组
    test_img_array =  np.array(test_img)  
    #归一化
    test_img_array =  test_img_array*(1.0/255.0) 
    # 转换为浮点型
    test_img_array = np.asarray(test_img_array,dtype='float32')

    #转换列表  转化成一阶张量
    test_img_array = list(chain.from_iterable(test_img_array))
    #转化为二阶张量
    test_img_array = [test_img_array]
    print(test_img_array)

    #参数提取
    with open(save_pic_name[i]+".h",'w') as f:
        new_str1 = str(test_img_array)
        new_str2 = new_str1.replace('[','')
        new_str3 = new_str2.replace(']','')
        f.write("float "+save_pic_name[i]+"[784]={"+new_str3+"};\n") 
        f.close()
    print("图片参数读取完成")

上述pic_n.bmp是从测试集中提取出来,重命名后的

提取结果如下:
在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值