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

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,操作更方便哦 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值