读一篇人工智能cnn gps返回图像识别器代码注释以及流程图

    技术2024-12-06  17

    1.代码  

    import dataset import tensorflow as tf import time from datetime import timedelta import math import random import numpy as np # conda install --channel https://conda.anaconda.org/menpo opencv3 #Adding Seed so that random initialization is consistent

    # 随机初始化:每一次随机都是相同的结果 from numpy.random import seed seed(10) # 数值随意,不改变就行 from tensorflow import set_random_seed set_random_seed(20)

    # 每次迭代送入32张图 batch_size = 28 # 指定标签:只有两种 classes = ['island','seaice'] # 一共有多少类别,最后训练需要 num_classes = len(classes)

    # 1000张图中,20%为测试集 validation_size = 0.2 # 由于图片有大有小,这里我设置/截所有图像为64x64 img_size = 64 # 彩色图:3通量 num_channels = 3 # 所有图像所在位置:training_data文件夹 train_path='training_data'

    # 调用dataset.py中的read_train_sets函数 # 目的:得到已处理好、分好的图片集 data = dataset.read_train_sets(train_path, img_size, classes, validation_size=validation_size)

    print("图片预处理完毕,分组如下:") print("训练集张数:{}".format(len(data.train.labels))) print("测试集张数:{}".format(len(data.valid.labels)))

     

    session = tf.Session() # 第一个参数是每次送入训练的张数;中间两个参数是图片的尺度:64x64;最后一个参数是3通量 x = tf.placeholder(tf.float32, shape=[None, img_size, img_size, num_channels], name='x')

    # 标签数 y_true = tf.placeholder(tf.float32, shape=[None, num_classes], name='y_true') # argmax判断当前哪个值大,就是什么 y_true_cls = tf.argmax(y_true, dimension=1)#y_true中每行最大原素的列坐标

     

    # 卷积网络结构设置 filter_size_conv1 = 3    # 卷积核1是3x3 num_filters_conv1 = 32   

    filter_size_conv2 = 3#第一部分是输入层。第二部分由n个卷积层和池化层的组合组成。第三部分由一个全连结的多层感知机分类器构成。 num_filters_conv2 = 32

    filter_size_conv3 = 3 num_filters_conv3 = 64      # 全连接层:1024个特征  常见还有2048 4096等等 fc_layer_size = 1024

    # 权重参数设置 def create_weights(shape):#创建w     return tf.Variable(tf.truncated_normal(shape, stddev=0.05))#产生截断正态分布随机数,取值范围为 [ mean - 2 * stddev, mean + 2 * stddev ]。

    def create_biases(size):#创建b     return tf.Variable(tf.constant(0.05, shape=[size]))#创建常量,shape:表示张量的“形状”,即维数以及每一维的大小(猜测创建值为0.05的大小为size的一为张量)

    # -------------------------------------------------------- # # 辅助函数1:卷积池化各层参数的设置与工作 def create_convolutional_layer(input,                num_input_channels, #深度                conv_filter_size,                        num_filters):            # 权重参数初始化:3 3 3 32     # 前两个参数是滑动窗尺寸3x3 第三个参数为3通量 第4个参数是这一层观察多少个特征     weights = create_weights(shape=[conv_filter_size, conv_filter_size, num_input_channels, num_filters])#将要创建的卷积核的大小,深度,个数都传递给crearte_weights函数生成随机权重     biases = create_biases(num_filters)#b的个数核卷积核的个数一致

        # 执行一次卷积操作     layer = tf.nn.conv2d(input=input,                      filter=weights,                      strides=[1, 1, 1, 1],                      padding='SAME')#tf.nn.conv2d输入参数直接进行了卷积运算

        layer += biases          # relu激活函数:激活后的数值传给下一步     layer = tf.nn.relu(layer)          # 池化操作:上一卷积层的输出就是这里的输入;池化窗尺寸为2x2     layer = tf.nn.max_pool(value=layer,                             ksize=[1, 2, 2, 1],                             strides=[1, 2, 2, 1],                             padding='SAME')

        # 一套卷积池化层工作完毕     return layer

    # 辅助函数2:全连接层参数的设置 def create_flatten_layer(layer):     # 把到最后一个卷积池化层的尺寸:[7,8,8,64]#如果这个地方是1那后面7全改一即可,应该是1     # 既然是全连接层,就要把它拉伸;即对这个全连接层的"输入"应有8x8x64=4096个     layer_shape = layer.get_shape()#layer_shape = [7,8,8,64]

        # 计算得到那个4096的数值     num_features = layer_shape[1:4].num_elements()#shape[1:4]切片数组得到[8,8,64]数组,num_elements()返回一个变量[8,8,64]的规模,也就是该变量的所有元素的数量。

        # 转换成数组/矩阵     layer = tf.reshape(layer, [-1, num_features])#-1是不确定值,通过7*8*8*64/8*8*64计算得出7#目前理解7是指七页

        return layer

    # 辅助函数3:全连接层创建与工作 def create_fc_layer(input,#7*4096 #7*1024                       num_inputs,# 8*8*64 = 4096  #1024               num_outputs,#1024 #2              use_relu=True):          # 全连接层的权重参数等的设置:前4096,后2048(自己之前设置过的)     weights = create_weights(shape=[num_inputs, num_outputs])#4096*1024#1024*2     biases = create_biases(num_outputs)#1024#2

        # 计算:     layer = tf.matmul(input, weights) + biases#矩阵7*4096和4096*1024的到7*1024#7*1024和1024*2得到7*2(即七张图每张图俩类别的概率)          # dropout解决过拟合,随机杀死30%个节点     layer=tf.nn.dropout(layer,keep_prob=0.7)          # relu激活函数     if use_relu:         layer = tf.nn.relu(layer)     return layer # -------------------------------------------------------- #     

    # 调用辅助函数1:第一套 “卷积池化层” 工作完毕 layer_conv1 = create_convolutional_layer(input=x,#x第47行shape=NONE                num_input_channels=num_channels,                conv_filter_size=filter_size_conv1,                num_filters=num_filters_conv1)

    # 调用辅助函数1:第二套 “卷积池化层” 工作完毕 layer_conv2 = create_convolutional_layer(input=layer_conv1,                num_input_channels=num_filters_conv1,                conv_filter_size=filter_size_conv2,                num_filters=num_filters_conv2)                 # 调用辅助函数1:第三套 “卷积池化层” 工作完毕 layer_conv3= create_convolutional_layer(input=layer_conv2,                num_input_channels=num_filters_conv2,                conv_filter_size=filter_size_conv3,                num_filters=num_filters_conv3)           # 调用辅助函数2:对下面的全连接层先设置相关的参数 layer_flat = create_flatten_layer(layer_conv3)

    # 调用辅助函数3:全连接层1工作 layer_fc1 = create_fc_layer(input=layer_flat,                      num_inputs=layer_flat.get_shape()[1:4].num_elements(),#                      num_outputs=fc_layer_size,                      use_relu=True)

    # 调用辅助函数3:全连接层2工作 layer_fc2 = create_fc_layer(input=layer_fc1,                      num_inputs=fc_layer_size,#1024                      num_outputs=num_classes,#2                      use_relu=False) 

    # 预测值:谁大选谁 y_pred = tf.nn.softmax(layer_fc2,name='y_pred') #softmax的输出向量,就是概率,该样本属于各个类的概率#softmax后为tensor y_pred_cls = tf.argmax(y_pred, dimension=1)#取行最大的 #这俩步作者为了打印与梯度下降操作无关

    # 以下是常规操作: session.run(tf.global_variables_initializer())# 必须要使用global_variables_initializer的场合 # 含有tf.Variable的环境下,因为tf中建立的变量是没有初始化的,也就是在debug时还不是一个tensor量,而是一个Variable变量类型 #简单来说初始化所有张量 cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=layer_fc2, labels=y_true)# #第一个参数logits:就是神经网络最后一层的输出,如果有batch的话,它的大小就是[batchsize,num_classes],单样本的话,大小就是num_classes #第二个参数labels:实际的标签,大小同上 #体的执行流程大概分为两步: #第一步是先对网络最后一层的输出做一个softmax, #这一步通常是求取输出属于某一类的概率,对于单样本而言,输出就是一个num_classes大小的向量([Y1,Y2,Y3...]其中Y1,Y2,Y3...分别代表了是属于该类的概率) #第二步是softmax的输出向量[Y1,Y2,Y3...]和样本的实际标签做一个交叉熵

    cost = tf.reduce_mean(cross_entropy)#结合上一步求loss#求损失值 #前三步为了最后一步优化器 optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cost)#tf.train.AdamOptimizer()函数是Adam优化算法: #是一个寻找全局最优点的优化算法,引入了二次方梯度校正。#学习率1e-4# #梯度下降函数,优化器就会按照循环的次数一次次沿着loss最小值的方向优化参数了。 #train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss) #优化器# train_step = tf.train.AdamOptimizer(0.001) #收敛速度比较快# train_step = tf.train.AdamOptimizer(1e-3).minimize(loss)  #10的-3次方,学习率, #此步骤定义好优化器 correct_prediction = tf.equal(y_pred_cls, y_true_cls)#判断预测和实际是否一致 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))#tf.cast将预测结果转换为float32后的张量的平均值 #也可以看成准确率

    session.run(tf.global_variables_initializer()) 

    # 打印: def show_progress(epoch, feed_dict_train, feed_dict_validate, val_loss,i):     acc = session.run(accuracy, feed_dict=feed_dict_train)     val_acc = session.run(accuracy, feed_dict=feed_dict_validate)     msg = "Training Epoch {0}--- iterations: {1}--- 训练集精度: {2:>6.1%}, 测试集精度: {3:>6.1%},  测试集损失值: {4:.3f}"     print(msg.format(epoch + 1,i, acc, val_acc, val_loss))     ftmp.write(msg.format(epoch + 1,i, acc, val_acc, val_loss))     ftmp.write('\n')     ftmp.flush()

    # 从第0次开始迭代 total_iterations = 0

    # 跑模型 + 模型保存: ftmp = open('result.txt','w') saver = tf.train.Saver() def train(num_iteration):     global total_iterations          for i in range(total_iterations,                    total_iterations + num_iteration):

            # 调用dataset.py文件中data类中的next_batch方法         x_batch, y_true_batch, _, cls_batch = data.train.next_batch(batch_size)#batch_size ==28         x_valid_batch, y_valid_batch, _, valid_cls_batch = data.valid.next_batch(batch_size)#每次迭代返回该段batch的 #images图片数据(矩阵) labels每张图片对应标签 img_names图片名字  cls每遍历一张图片就记录该图片类别的列表         # 做好每一个epoch         feed_dict_tr = {x: x_batch, y_true: y_true_batch}         feed_dict_val = {x: x_valid_batch, y_true: y_valid_batch}

            # 开始运行训练         session.run(optimizer, feed_dict=feed_dict_tr)#我们在编写代码的时候,总是要先定义好整个图,然后才调用sess.run()。         #feed_dict参数的作用是替换图中的某个tensor的值或设置graph的输入值。         #相当于定义好了张量a和b以及操作(,这一步执行。         # 打印:         if i % int(data.train.num_examples/batch_size) == 0:              # 损失值             val_loss = session.run(cost, feed_dict=feed_dict_val)               epoch = int(i / int(data.train.num_examples/batch_size))                              show_progress(epoch, feed_dict_tr, feed_dict_val, val_loss,i)             # 保存文件夹的地方             saver.save(session, './model/island-seaice.ckpt',global_step=i) 

        total_iterations += num_iteration

    # 调用train函数:规定一共迭代4000次 train(num_iteration=4000)

    2.详细流程图  

     

    源码:

    链接:https://pan.baidu.com/s/1NyNoIqXJ7bg_X-ZW4UFhug  提取码:7krh  复制这段内容后打开百度网盘手机App,操作更方便哦 

    Processed: 0.045, SQL: 9