摘要:这篇文章将解说TensorFlow如何保留变量和神经网络参数,通过Saver保留神经网络,再通过Restore调用训练好的神经网络。

本文分享自华为云社区《[[Python人工智能] 十一.Tensorflow如何保留神经网络参数 丨【百变AI秀】](https://bbs.huaweicloud.com/b...)》,作者: eastmount。

一.保留变量

通过tf.Variable()定义权重和偏置变量,而后调用tf.train.Saver()存储变量,将数据保留至本地“my_net/save_net.ckpt”文件中。

# -*- coding: utf-8 -*-"""Created on Thu Jan  2 20:04:57 2020@author: xiuzhang Eastmount CSDN"""import tensorflow as tfimport numpy as np#---------------------------------------保留文件---------------------------------------W = tf.Variable([[1,2,3], [3,4,5]], dtype=tf.float32, name='weights') #2行3列的数据b = tf.Variable([[1,2,3]], dtype=tf.float32, name='biases')# 初始化init = tf.initialize_all_variables()# 定义saver 存储各种变量saver = tf.train.Saver()# 应用Session运行初始化with tf.Session() as sess:    sess.run(init)    # 保留 官网保留格局为ckpt    save_path = saver.save(sess, "my_net/save_net.ckpt")    print("Save to path:", save_path)

“Save to path: my_net/save_net.ckpt”保留胜利如下图所示:

关上内容如下图所示:

接着定义标记变量train,通过Restore操作应用咱们保留好的变量。留神,在Restore时须要定义雷同的dtype和shape,不须要再定义init。最初间接通过 saver.restore(sess, “my_net/save_net.ckpt”) 提取保留的变量并输入即可。

# -*- coding: utf-8 -*-"""Created on Thu Jan  2 20:04:57 2020@author: xiuzhang Eastmount CSDN"""import tensorflow as tfimport numpy as np# 标记变量train = False#---------------------------------------保留文件---------------------------------------# Saveif train==True:    # 定义变量    W = tf.Variable([[1,2,3], [3,4,5]], dtype=tf.float32, name='weights') #2行3列的数据    b = tf.Variable([[1,2,3]], dtype=tf.float32, name='biases')    # 初始化    init = tf.global_variables_initializer()     # 定义saver 存储各种变量    saver = tf.train.Saver()     # 应用Session运行初始化    with tf.Session() as sess:        sess.run(init)        # 保留 官网保留格局为ckpt        save_path = saver.save(sess, "my_net/save_net.ckpt")        print("Save to path:", save_path)#---------------------------------------Restore变量-------------------------------------# Restoreif train==False:    # 记住在Restore时定义雷同的dtype和shape    # redefine the same shape and same type for your variables    W = tf.Variable(np.arange(6).reshape((2,3)), dtype=tf.float32, name='weights') #空变量    b = tf.Variable(np.arange(3).reshape((1,3)), dtype=tf.float32, name='biases') #空变量     # Restore不须要定义init    saver = tf.train.Saver()    with tf.Session() as sess:        # 提取保留的变量        saver.restore(sess, "my_net/save_net.ckpt")        # 寻找雷同名字和标识的变量并存储在W和b中        print("weights", sess.run(W))        print("biases", sess.run(b))

运行代码,如果报错“NotFoundError: Restoring from checkpoint failed. This is most likely due to a Variable name or other graph key that is missing from the checkpoint. Please ensure that you have not altered the graph expected based on the checkpoint. ”,则须要重置Spyder即可。

最初输入之前所保留的变量,weights为 [[1,2,3], [3,4,5]],偏置为 [[1,2,3]]。

二.保留神经网络

那么,TensorFlow如何保留咱们的神经网络框架呢?咱们须要把整个网络训练好再进行保留,其办法和下面相似,残缺代码如下:

"""Created on Sun Dec 29 19:21:08 2019@author: xiuzhang Eastmount CSDN"""import osimport globimport cv2import numpy as npimport tensorflow as tf# 定义图片门路path = 'photo/'#---------------------------------第一步 读取图像-----------------------------------def read_img(path):    cate = [path + x for x in os.listdir(path) if os.path.isdir(path + x)]    imgs = []    labels = []    fpath = []    for idx, folder in enumerate(cate):        # 遍历整个目录判断每个文件是不是合乎        for im in glob.glob(folder + '/*.jpg'):            #print('reading the images:%s' % (im))            img = cv2.imread(im)             #调用opencv库读取像素点            img = cv2.resize(img, (32, 32))  #图像像素大小统一            imgs.append(img)                 #图像数据            labels.append(idx)               #图像类标            fpath.append(path+im)            #图像路径名            #print(path+im, idx)     return np.asarray(fpath, np.string_), np.asarray(imgs, np.float32), np.asarray(labels, np.int32)# 读取图像fpaths, data, label = read_img(path)print(data.shape)  # (1000, 256, 256, 3)# 计算有多少类图片num_classes = len(set(label))print(num_classes)# 生成等差数列随机调整图像程序num_example = data.shape[0]arr = np.arange(num_example)np.random.shuffle(arr)data = data[arr]label = label[arr]fpaths = fpaths[arr]# 拆分训练集和测试集 80%训练集 20%测试集ratio = 0.8s = np.int(num_example * ratio)x_train = data[:s]y_train = label[:s]fpaths_train = fpaths[:s] x_val = data[s:]y_val = label[s:]fpaths_test = fpaths[s:] print(len(x_train),len(y_train),len(x_val),len(y_val)) #800 800 200 200print(y_val)#---------------------------------第二步 建设神经网络-----------------------------------# 定义Placeholderxs = tf.placeholder(tf.float32, [None, 32, 32, 3])  #每张图片32*32*3个点ys = tf.placeholder(tf.int32, [None])               #每个样本有1个输入# 寄存DropOut参数的容器 drop = tf.placeholder(tf.float32)                   #训练时为0.25 测试时为0# 定义卷积层 conv0conv0 = tf.layers.conv2d(xs, 20, 5, activation=tf.nn.relu)    #20个卷积核 卷积核大小为5 Relu激活# 定义max-pooling层 pool0pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2])        #pooling窗口为2x2 步长为2x2print("Layer0:\n", conv0, pool0) # 定义卷积层 conv1conv1 = tf.layers.conv2d(pool0, 40, 4, activation=tf.nn.relu) #40个卷积核 卷积核大小为4 Relu激活# 定义max-pooling层 pool1pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2])        #pooling窗口为2x2 步长为2x2print("Layer1:\n", conv1, pool1)# 将3维特色转换为1维向量flatten = tf.layers.flatten(pool1)# 全连贯层 转换为长度为400的特征向量fc = tf.layers.dense(flatten, 400, activation=tf.nn.relu)print("Layer2:\n", fc)# 加上DropOut避免过拟合dropout_fc = tf.layers.dropout(fc, drop)# 未激活的输入层logits = tf.layers.dense(dropout_fc, num_classes)print("Output:\n", logits)# 定义输入后果predicted_labels = tf.arg_max(logits, 1)#---------------------------------第三步 定义损失函数和优化器---------------------------------# 利用穿插熵定义损失losses = tf.nn.softmax_cross_entropy_with_logits(        labels = tf.one_hot(ys, num_classes),       #将input转化为one-hot类型数据输入        logits = logits)# 均匀损失mean_loss = tf.reduce_mean(losses)# 定义优化器 学习效率设置为0.0001optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(losses)#------------------------------------第四步 模型训练和预测-----------------------------------# 用于保留和载入模型saver = tf.train.Saver()# 训练或预测train = False# 模型文件门路model_path = "model/image_model"with tf.Session() as sess:    if train:        print("训练模式")        # 训练初始化参数        sess.run(tf.global_variables_initializer())        # 定义输出和Label以填充容器 训练时dropout为0.25        train_feed_dict = {                xs: x_train,                ys: y_train,                drop: 0.25        }        # 训练学习1000次        for step in range(1000):            _, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)            if step % 50 == 0:  #每隔50次输入一次后果                print("step = {}\t mean loss = {}".format(step, mean_loss_val))        # 保留模型        saver.save(sess, model_path)        print("训练完结,保留模型到{}".format(model_path))    else:        print("测试模式")        # 测试载入参数        saver.restore(sess, model_path)        print("从{}载入模型".format(model_path))        # label和名称的对照关系        label_name_dict = {            0: "人类",            1: "沙滩",            2: "修建",            3: "公交",            4: "恐龙",            5: "大象",            6: "花朵",            7: "野马",            8: "雪山",            9: "美食"        }        # 定义输出和Label以填充容器 测试时dropout为0        test_feed_dict = {            xs: x_val,            ys: y_val,            drop: 0        }         # 实在label与模型预测label        predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)        for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):            # 将label id转换为label名            real_label_name = label_name_dict[real_label]            predicted_label_name = label_name_dict[predicted_label]            print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))        # 评估后果        print("正确预测个数:", sum(y_val==predicted_labels_val))        print("准确度为:", 1.0*sum(y_val==predicted_labels_val) / len(y_val))

外围步骤为:

saver = tf.train.Saver()model_path = "model/image_model"with tf.Session() as sess:    if train:        #保留神经网络        sess.run(tf.global_variables_initializer())        for step in range(1000):            _, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)            if step % 50 == 0:                print("step = {}\t mean loss = {}".format(step, mean_loss_val))        saver.save(sess, model_path)    else:        #载入神经网络        saver.restore(sess, model_path)        predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)        for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):            real_label_name = label_name_dict[real_label]            predicted_label_name = label_name_dict[predicted_label]            print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))    

预测输入后果如下图所示,最终预测正确181张图片,准确度为0.905。相比之前机器学习KNN的0.500有十分高的晋升。

测试模式

INFO:tensorflow:Restoring parameters from model/image_model从model/image_model载入模型b'photo/photo/3\\335.jpg'       公交 => 公交b'photo/photo/1\\129.jpg'       沙滩 => 沙滩b'photo/photo/7\\740.jpg'       野马 => 野马b'photo/photo/5\\564.jpg'       大象 => 大象...b'photo/photo/9\\974.jpg'       美食 => 美食b'photo/photo/2\\220.jpg'       修建 => 公交b'photo/photo/9\\912.jpg'       美食 => 美食b'photo/photo/4\\459.jpg'       恐龙 => 恐龙b'photo/photo/5\\525.jpg'       大象 => 大象b'photo/photo/0\\44.jpg'        人类 => 人类正确预测个数: 181准确度为: 0.905

点击关注,第一工夫理解华为云陈腐技术~