卷积神经网络中loss值为nan的问题(已解决)

卷积神经网络中loss值为nan的问题(已经解决了,请看最后的说明)

最近一直在学习AI方面的东西。想自己搞一个类似MINST的东东,用搞基神经网络 ,样本用自制的样本……然鹅理想是骨感的,现实是永远吃不上饭的。经过与各种错误轮战后,出现了更大的错误:loss为nan

先上代码吧,比较乱,建议摘了眼镜看:
首先是整体代码:

import os
import glob
from skimage import io,transform
import numpy as np
import cv2
import matplotlib.pyplot as plt
import tensorflow as tf
import time

# path = "E:\\study\\MINST-PLUS\\data"
# data_size = [28,28,3]
def read_img (path, data_size):
    imgs = []
    labels = []
    cate = []
    for x in os.listdir(path):            # 读取文件夹里所有文件夹的路径,赋值到cate列表
        if (os.path.isdir(path+'\\'+x)):
            cate.append(path+'\\'+x)

    # cate=[path+x for x in os.listdir(path) if os.path.isdir(path+x)] 大神都这样写,但是不好理解,有些太perl

    for idx,folder in enumerate(cate):    #给文件夹排序号,0是0文件夹,1是1文件夹...
        for im in glob.glob(folder+'/*.jpg'): #遍历文件夹内的*.jpg文件(路径)
#            print(im)
            img = cv2.imread(im)  #读取jpg文件
#            img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)  #把图片转换为黑白(彩色是3维,黑白是2维)
            img = cv2.resize(img,(data_size[0],data_size[1]),interpolation=cv2.INTER_CUBIC)
            # 根据要求调整图片大小
#            img = 255 - img                 # 以下为图片的处理 ,先减去一个255
#            for row in range(img.shape[0]):
#                for col in range(img.shape[1]):
#                    if img[row][col] < 120.0:   #把灰度120以下的化为0(降噪)
#                        img[row][col] = 0

#            img = img / 255  # 把各个直降到1-0之间的小数
            imgs.append(img) # 追加到数组imgs
            labels.append(idx) # 追加到数组labels
#            plt.imshow(img,'gray')
#            plt.show()
#            print(np.shape(labels))
#            print(np.shape(img))  #注意img是单张图片是32*32的二维数组
#            print(np.shape(imgs)) #但是imgs是:第几张图片*32*32 的三维数组,现在我有160张图片,所以是 160*28*28
#            print (labels)         #标签的顺序也是依照图片的顺序匹配的,也就是:imgs[0] 这个图片的标签是labels[0]
#            print (len(labels))    #相对的labels的总数,到现在为止是160个标签
    np.asarray(imgs,np.float32),np.asarray(labels,np.float32)  # 将数组转化为矩阵
    return np.asarray(imgs,np.float32),np.asarray(labels,np.float32)
# 以上我把图片转换为灰度图的代码注释掉了,现在是直接读取的图片。




def data_split_flow (data,label,ratio):# data是读取的图片集合,label是图片的标签集合,ratio是你想要(百分之)多少数据用于培训.
    num_example = data.shape[0]  # 这个data是读取图片的合计,其中第一维就是图片的序号,也就是图片的总量
    arr = np.arange(num_example) # np.arange(起始值,终止值,步长) 与arange(起始值,终止值,步长) 不同之处是np.arange的参数可以是小数,这里应该是np.arange(28)
    np.random.shuffle(arr) #随机打乱顺序函数,多维矩阵中,只对第一维做打乱顺序操作。也就是np.arange(28)中的顺序被随机打乱
#    print (type(arr))
#    print (type(data))
#    print (data.shape)
    data = data[arr]  # 因为arr现在是一维的随机化的np矩阵,用它可以覆盖掉原数据的第一维,也就是重新给data排序
    label = label[arr] # 同理,也同样使label标签随机化,这两次随机化的参数arr是相同的,也就是随机后的数据和标签是可以对上号的。
#    print (data.shape)
    s = np.int(num_example*ratio)  # 图片总数*想要取走百分之多少,并且取整,然后赋予s

    x_train = data[:s]  #以下是把图片分为“训练用图片”“训练用图片的标签”,“验证用图片”“验证用图片的标签”。其中[:s]或[s:]是列表的切片,表示由开始到s,或由s到最后。
    y_train = label[:s]
    x_val = data[s:]
    y_val = label[s:]

    return x_train,y_train,x_val,y_val
#c,d,e,f = data_split_flow(a,b,0.8)


def cnn_fc (input_tensor,train,regularizer):
    with tf.variable_scope('layer1-conv1'): # 开启一个联系上下文的命名空间,空间名是layer1-conv1,在tf.get_variable可以顺利调用
        conv1_weights = tf.get_variable('weight',[5,5,3,6],initializer = tf.truncated_normal_initializer(stddev = 0.1))
        #上面一行命令是生成卷积核:是一个tansor类型,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维
            # tf.truncated_normal_initializer:从截断的正态分布中输出随机值。这是神经网络权重和过滤器的推荐初始值。
            # mean:一个python标量或一个标量张量。要生成的随机值的均值。
            # stddev:一个python标量或一个标量张量。要生成的随机值的标准偏差。
            # seed:一个Python整数。用于创建随机种子。查看 tf.set_random_seed 行为。
            # dtype:数据类型。只支持浮点类型。
        conv1_biases = tf.get_variable("bias",[6],initializer = tf.constant_initializer(0.0))
        conv1 = tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding="SAME")
        # 除去name参数用以指定该操作的name,与方法有关的一共五个参数:
        #第一个参数input:指需要做卷积的输入图像,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]这样的shape,
        #具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一

        #第二个参数filter:相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels, out_channels]这样的shape,
        #具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维

        #第三个参数strides:卷积时在图像每一维的步长,这是一个一维的向量,长度4
        #第四个参数padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式(后面会介绍)
        #第五个参数:use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true#    
        #结果返回一个Tensor,这个输出,就是我们常说的feature map特征图,shape仍然是[batch, height, width, channels]这种形式。

        relu1 = tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases))
        # 激活函数,非最大值置零
        # 这个函数的作用是计算激活函数 relu,即 max(features, 0)。即将矩阵中每行的非最大值置0。

    with tf.name_scope("layer2-pool1"):
        pool1 = tf.nn.max_pool(relu1,ksize = [1,2,2,1], strides=[1,2,2,1],padding="VALID")
        #tf.nn.max_pool(value, ksize, strides, padding, name=None)
        #参数是四个,和卷积很类似:
        #第一个参数value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch, height, width, channels]这样的shape
        #第二个参数ksize:池化窗口的大小,取一个四维向量,一般是[1, height, width, 1],因为我们不想在batch和channels上做池化,所以这两个维度设为了1
        #第三个参数strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride,stride, 1]
        #第四个参数padding:和卷积类似,可以取'VALID' 或者'SAME'
        #返回一个Tensor,类型不变,shape仍然是[batch, height, width, channels]这种形式

    with tf.variable_scope("layer3-conv2"):
        conv2_weights = tf.get_variable("weight",[5,5,6,16],initializer=tf.truncated_normal_initializer(stddev=0.1))# [5,5,32,64] 5表示本次卷积核高宽,32表示经过上一层32个卷积核的卷积,我们有了32张特征图,64表明本次会有64个卷积核卷积
        conv2_biases = tf.get_variable("bias", [16], initializer=tf.constant_initializer(0.0))
        conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))

    with tf.name_scope("layer4-pool2"):
        pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
        nodes = 8*8*16
        reshaped = tf.reshape(pool2,[-1,nodes])  # 其中pool2是链接上一层,我把pool4和pool3的卷积核池化层删除了,卷的太多都要成渣渣了。
        # tf.reshape(tensor(矩阵),shape(维度),name=None)
        # 改变一个矩阵的维度,可以从多维变到一维,也可以从一维变到多维
        # 其中,-1参数表示不确定,可由函数自己计算出来,原矩阵/一个维度=另一个维度

    with tf.variable_scope('layer9-fc1'):
        fc1_weights = tf.get_variable("weight", [nodes, 1024],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc1_weights))
        # tf.add_to_collection:把变量放入一个集合,把很多变量变成一个列表
        #在深度学习中,通常用这几个函数存放不同层中的权值和偏置参数,
        #也就是把所有可学习参数利用tf.contrib.layers.l2_regularizer(regular_num)(w)得到norm后,都放到’regular’的列表中作为正则项,
        #然后使用tf.add_n函数将他们和原本的loss相加,得到含有正则的loss。
        fc1_biases = tf.get_variable("bias", [1024], initializer=tf.constant_initializer(0.1))

        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases) # MCP模型
        if train: fc1 = tf.nn.dropout(fc1, 0.5) #tf.nn.dropout是TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层。

        # tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None,name=None) 
        # 上面方法中常用的是前两个参数:
        # 第一个参数x:指输入的数据。
        # 第二个参数keep_prob: 设置神经元被选中的概率,在初始化时keep_prob是一个占位符,  keep_prob = tf.placeholder(tf.float32) 。
        # tensorflow在run时设置keep_prob具体的值,例如keep_prob: 0.5
        # 第五个参数name:指定该操作的名字。


    with tf.variable_scope('layer10-fc2'):
        fc2_weights = tf.get_variable("weight", [1024, 512],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc2_weights))
        fc2_biases = tf.get_variable("bias", [512], initializer=tf.constant_initializer(0.1))

        fc2 = tf.nn.relu(tf.matmul(fc1, fc2_weights) + fc2_biases)
        if train: fc2 = tf.nn.dropout(fc2, 0.5)

    with tf.variable_scope('layer11-fc3'):
        fc3_weights = tf.get_variable("weight", [512, 5],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc3_weights))
        fc3_biases = tf.get_variable("bias", [5], initializer=tf.constant_initializer(0.1))
        logit = tf.matmul(fc2, fc3_weights) + fc3_biases
#        variable_summaries(fc3_weights)
#        variable_summaries(fc3_biases)

    return logit


def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False): #四个参数是:训练数据,测试数据,用户输入的每批训练的数据数量,shuffle是洗牌的意思,这里表示是否开始随机。
    assert len(inputs) == len(targets)  #assert断言机制,如果后面的表达式为真,则直接抛出异常。在这里的意思,大概就是:样本和标签数量要对上
    if shuffle:
        indices = np.arange(len(inputs)) #生成一个np.arange可迭代长度是len(训练数据),也就是训练数据第一维数据的数量(就是训练数据的数量,训练图片的数量)。
        np.random.shuffle(indices)  #np.random.shuffle打乱arange中的顺序,使其随机循序化,如果是数组,只打乱第一维。
    for start_idx in range(0, len(inputs) - batch_size + 1, batch_size): # 这个range(初始值为0,终止值为[训练图片数-每批训练图片数+1],步长是[每批训练图片数]):例(0[起始值],80[训练图片数]-20[每批训练图片数],20[每批训练图片数]),也就是(0,60,20)当循环到60时,会加20到达80的训练样本.
        if shuffle:
            excerpt = indices[start_idx:start_idx + batch_size] # 如果shuffle为真,将indices列表,切片(一批)赋值给excerpt
        else:
            excerpt = slice(start_idx, start_idx + batch_size) # 如果shuffle为假,将slice()函数(切片函数),实例化,初始值为start_idx,结束为止为start_idx + batch_size(也就是根据上一批起始,算出本批结束的位置.),间距为默认.
        yield inputs[excerpt], targets[excerpt]
        #yield常见用法:该关键字用于函数中会把函数包装为generator。然后可以对该generator进行迭代: for x in fun(param).
        #按照我的理解,可以把yield的功效理解为暂停和播放。
        #在一个函数中,程序执行到yield语句的时候,程序暂停,返回yield后面表达式的值,在下一次调用的时候,从yield语句暂停的地方继续执行,如此循环,直到函数执行完。
        #此处,就是返回每次循环中 从inputs和targets列表中,截取的 经过上面slice()切片函数定义过的 数据.
        #(最后的shuffle变量,决定了样本是否随机化)

# 设置超参
path = "E:\\study\\MINST-PLUS\\data"
data_size = [32,32,3]
data_ratio = 0.6
is_train = False
epoch = 5
batch_size = 4

# 样本和标签的读入与分类
data,label = read_img(path,data_size)
x_train,y_train,x_val,y_val = data_split_flow(data,label,data_ratio)

# 为数据与标签设立两个存放空间
x = tf.placeholder(tf.float32,shape=[None,data_size[0],data_size[1],data_size[2]],name = 'x') # 如果是灰度图,通道应该是1,彩色是3
y_ = tf.placeholder(tf.int32,shape=[None,],name = 'y_')

# 定义规则化方法,并计算网络激活值
regularizer = tf.contrib.layers.l2_regularizer(0.0001)   # 过拟合与正则化(regularizer),这个regularizer就是inference函数的最后一个参数。
#两种思想都是希望限制权重的大小,使得模型不能拟合训练数据中的随机噪点。(两种思想,就是两个公式,因为是图,就没贴出来)
#两种方式在TensorFlow中的提供的函数为:
#tf.contrib.layers.l1_regularizer(scale, scope=None) 其中scale为权值(这个权值会乘以w的值,MCP的内个w,江湖传闻w和过拟合值有说不清的关系)
#tf.contrib.layers.l2_regularizer(scale, scope=None)

logits = cnn_fc(x,is_train,regularizer)  #x是输入的图像的tansor,logits是经过卷积、池化、全连接处理处理过的数据
# b = tf.constant(value=1,dtype=tf.float32)  # constant(值、列表 , 数组格式)根据值、列表,生成一个数组,格式为“数组格式”
# logits_eval = tf.multiply(logits,b,name='logits_eval') # 额,不知道这是计算啥

# 计算误差与准确率,并写入日志 (我没有日志,呵呵)
loss = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=logits) #计算logits 和 labels 之间的稀疏softmax 交叉熵 这个是计算误差率

train_op = tf.train.AdamOptimizer(learning_rate=0.01).minimize(loss)  # tf.train.AdamOptimizer 优化器中的梯度优化函数,
# 作用是依据learning_rate步长,来最小化loss误差率。

correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_)
#tf.argmax(vector, 1):返回的是vector中的最大值的索引号,如果vector是一个向量,那就返回一个值,如果是一个矩阵,那就返回一个向量,
#这个向量的每一个维度都是相对应矩阵行的最大值元素的索引号。

# tf.cast(x, dtype, name=None)
# 此函数是类型转换函数
# 参数
# x:输入
# dtype:转换目标类型
# name:名称
# 返回:Tensor

# tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,
# 返回的值的矩阵维度和A是一样的,返回的也是一个矩阵、向量、列表,里面都是true和false。

#这一行的意思,大概是,通过以上三个函数,对比处理后的logits值和labels值,然后得出一个判断表单

acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) #这个......大概是在计算准确率
# 求平均值tf.reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)
# 参数1--input_tensor:待求值的tensor。
# 参数2--reduction_indices:在哪一维上求解。
# 参数(3)(4)可忽略

# tf.summary.scalar('accuracy', acc)

# 创建保存点,并进入计算图流程   还有限制gpu,我的电脑没有这句话就各种死
saver=tf.train.Saver()
sess=tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True))  #限制gpu内存
sess.run(tf.global_variables_initializer())   # 全世界get_variable嗨起来

# 定义日志汇总操作,初始化训练日志与验证日志的writer

# 我木有日志,呵呵

# 开始训练:第一个for循环,是总体训练的次数。第一个for子循环是训练样本循环,当其结束也就是训练样本被整体遍历了一次。第二个也一样,不过是验证样本。
for epoch in range(epoch):   # 训练多少遍,FLAGS.epoch是用户输入的,比如是5,也就是把样本遍历5遍
    start_time = time.time()       # 开始计时

    ### 单次训练部分  此处for循环结束之日,就是训练样本遍历了一遍之时......
    train_loss, train_acc, n_batch = 0, 0, 0    # 先定义下训练误差,训练识别率,训练批次
    for x_train_a, y_train_a in minibatches(x_train, y_train,batch_size, shuffle=True):  
    #遍历minibatches函数,因为这个函数中有yield关键字,每次for,会获取到不同的批次,直到训练样本集合身体被掏空。注意,这里shuffle为True,样本是随机的。
        _, err, ac = sess.run([train_op, loss, acc], feed_dict={x: x_train_a, y_: y_train_a})  #向sess.run中喂数据,
        # 其中merged是train_summary计算图;train_op是梯度优化方法,err接收的loss是误差率;ac接收的acc是准确率。后面的x和y_就是每批的数据和标签。
        train_loss += err; train_acc += ac; n_batch += 1  #统计误差率、准确率、批次
    print("   train loss: %f" % (np.sum(train_loss)/ n_batch))
    print("   train acc: %f" % (np.sum(train_acc)/ n_batch))

    ### 单次验证部分   具体和上面雷同,下面是计算的测试数据,不用梯度优化了
    val_loss, val_acc, n_batch = 0, 0, 0
    for x_val_a, y_val_a in minibatches(x_val, y_val,batch_size, shuffle=False):
        err, ac = sess.run([loss, acc], feed_dict={x: x_val_a, y_: y_val_a})
        val_loss += err; val_acc += ac; n_batch += 1
    print("   validation loss: %f" % (np.sum(val_loss)/ n_batch))
    print("   validation acc: %f" % (np.sum(val_acc)/ n_batch))
    print('-------------------------------------------------------')
## 保存模型
# saver.save(sess,FLAGS.model_dir)
sess.close()

#### 下面是测试输出logits值和loss值的代码:

import os
import glob
from skimage import io,transform
import numpy as np
import cv2
import matplotlib.pyplot as plt
import tensorflow as tf
import time

def read_img (path, data_size):
    imgs = []
    labels = []
    cate = []
    for x in os.listdir(path):            # 读取文件夹里所有文件夹的路径,赋值到cate列表
        if (os.path.isdir(path+'\\'+x)):
            cate.append(path+'\\'+x)

    # cate=[path+x for x in os.listdir(path) if os.path.isdir(path+x)] 大神都这样写,但是不好理解,有些太perl

    for idx,folder in enumerate(cate):    #给文件夹排序号,0是0文件夹,1是1文件夹...
        for im in glob.glob(folder+'/*.jpg'): #遍历文件夹内的*.jpg文件(路径)
#            print(im)
            img = cv2.imread(im)  #读取jpg文件
#            img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)  #把图片转换为黑白(彩色是3维,黑白是2维)
            img = cv2.resize(img,(data_size[0],data_size[1]),interpolation=cv2.INTER_CUBIC)
            # 根据要求调整图片大小
#            img = 255 - img                 # 以下为图片的处理 ,先减去一个255
#            for row in range(img.shape[0]):
#                for col in range(img.shape[1]):
#                    if img[row][col] < 120.0:   #把灰度120以下的化为0(降噪)
#                        img[row][col] = 0

#            img = img / 255  # 把各个直降到1-0之间的小数
            imgs.append(img) # 追加到数组imgs
            labels.append(idx) # 追加到数组labels
#            plt.imshow(img,'gray')
#            plt.show()
#            print(np.shape(labels))
#            print(np.shape(img))  #注意img是单张图片是32*32的二维数组 
#            print(np.shape(imgs)) #但是imgs是:第几张图片*32*32 的三维数组,现在我有54张图片,所以是 54*32*32
#            print (labels)         #标签的顺序也是依照图片的顺序匹配的,也就是:imgs[0] 这个图片的标签是labels[0]
#            print (len(labels))    #相对的labels的总数,到现在为止是160个标签
#            因为在给卷积函数数据时是[每批的样本数量,样本长,样本宽,样本通道数],如果是灰度图,是没有通道数的,需要增加一维,此处我想做彩色的,所以把之前的彩色转换为灰度,注释掉了。
    np.asarray(imgs,np.float32),np.asarray(labels,np.float32)  # 将数组转化为矩阵
    return np.asarray(imgs,np.float32),np.asarray(labels,np.float32)




def data_split_flow (data,label,ratio):# data是读取的图片集合,label是图片的标签集合,ratio是你想要(百分之)多少数据用于培训.
    num_example = data.shape[0]  # 这个data是读取图片的合计,其中第一维就是图片的序号,也就是图片的总量
    arr = np.arange(num_example) # np.arange(起始值,终止值,步长) 与arange(起始值,终止值,步长) 不同之处是np.arange的参数可以是小数,这里应该是np.arange(28)
    np.random.shuffle(arr) #随机打乱顺序函数,多维矩阵中,只对第一维做打乱顺序操作。也就是np.arange(28)中的顺序被随机打乱
#    print (type(arr))
#    print (type(data))
#    print (data.shape)
    data = data[arr]  # 因为arr现在是一维的随机化的np矩阵,用它可以覆盖掉原数据的第一维,也就是重新给data排序
    label = label[arr] # 同理,也同样使label标签随机化,这两次随机化的参数arr是相同的,也就是随机后的数据和标签是可以对上号的。
#    print (data.shape)
    s = np.int(num_example*ratio)  # 图片总数*想要取走百分之多少,并且取整,然后赋予s

    x_train = data[:s]  #以下是把图片分为“训练用图片”“训练用图片的标签”,“验证用图片”“验证用图片的标签”。其中[:s]或[s:]是列表的切片,表示由开始到s,或由s到最后。
    y_train = label[:s]
    x_val = data[s:]
    y_val = label[s:]

    return x_train,y_train,x_val,y_val
#c,d,e,f = data_split_flow(a,b,0.8)

def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False): #四个参数是:训练数据,测试数据,用户输入的每批训练的数据数量,shuffle是洗牌的意思,这里表示是否开始随机。
    assert len(inputs) == len(targets)  #assert断言机制,如果后面的表达式为真,则直接抛出异常。在这里的意思,大概就是:样本和标签数量要对上
    if shuffle:
        indices = np.arange(len(inputs)) #生成一个np.arange可迭代长度是len(训练数据),也就是训练数据第一维数据的数量(就是训练数据的数量,训练图片的数量)。
        np.random.shuffle(indices)  #np.random.shuffle打乱arange中的顺序,使其随机循序化,如果是数组,只打乱第一维。
    for start_idx in range(0, len(inputs) - batch_size + 1, batch_size): # 这个range(初始值为0,终止值为[训练图片数-每批训练图片数+1],步长是[每批训练图片数]):例(0[起始值],80[训练图片数]-20[每批训练图片数],20[每批训练图片数]),也就是(0,60,20)当循环到60时,会加20到达80的训练样本.
        if shuffle:
            excerpt = indices[start_idx:start_idx + batch_size] # 如果shuffle为真,将indices列表,切片(一批)赋值给excerpt
        else:
            excerpt = slice(start_idx, start_idx + batch_size) # 如果shuffle为假,将slice()函数(切片函数),实例化,初始值为start_idx,结束为止为start_idx + batch_size(也就是根据上一批起始,算出本批结束的位置.),间距为默认.
        yield inputs[excerpt], targets[excerpt]
        #yield常见用法:该关键字用于函数中会把函数包装为generator。然后可以对该generator进行迭代: for x in fun(param).
        #按照我的理解,可以把yield的功效理解为暂停和播放。
        #在一个函数中,程序执行到yield语句的时候,程序暂停,返回yield后面表达式的值,在下一次调用的时候,从yield语句暂停的地方继续执行,如此循环,直到函数执行完。
        #此处,就是返回每次循环中 从inputs和targets列表中,截取的 经过上面slice()切片函数定义过的 数据.
        #(最后的shuffle变量,决定了样本是否随机化)

def cnn_fc (input_tensor,train,regularizer):
    with tf.variable_scope('layer1-conv1'): # 开启一个联系上下文的命名空间,空间名是layer1-conv1,在tf.get_variable可以顺利调用
        conv1_weights = tf.get_variable('weight',[5,5,3,6],initializer = tf.truncated_normal_initializer(stddev = 0.1))
        #上面一行命令是生成卷积核:是一个tansor类型,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维
            # tf.truncated_normal_initializer:从截断的正态分布中输出随机值。这是神经网络权重和过滤器的推荐初始值。
            # mean:一个python标量或一个标量张量。要生成的随机值的均值。
            # stddev:一个python标量或一个标量张量。要生成的随机值的标准偏差。
            # seed:一个Python整数。用于创建随机种子。查看 tf.set_random_seed 行为。
            # dtype:数据类型。只支持浮点类型。
        conv1_biases = tf.get_variable("bias",[6],initializer = tf.constant_initializer(0.0))
        conv1 = tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding="SAME")
        # 除去name参数用以指定该操作的name,与方法有关的一共五个参数:
        #第一个参数input:指需要做卷积的输入图像,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]这样的shape,
        #具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一

        #第二个参数filter:相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels, out_channels]这样的shape,
        #具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维

        #第三个参数strides:卷积时在图像每一维的步长,这是一个一维的向量,长度4
        #第四个参数padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式(后面会介绍)
        #第五个参数:use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true#    
        #结果返回一个Tensor,这个输出,就是我们常说的feature map特征图,shape仍然是[batch, height, width, channels]这种形式。

        relu1 = tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases))
        # 激活函数,非最大值置零
        # 这个函数的作用是计算激活函数 relu,即 max(features, 0)。即将矩阵中每行的非最大值置0。

    with tf.name_scope("layer2-pool1"):
        pool1 = tf.nn.max_pool(relu1,ksize = [1,2,2,1], strides=[1,2,2,1],padding="VALID")
        #tf.nn.max_pool(value, ksize, strides, padding, name=None)
        #参数是四个,和卷积很类似:
        #第一个参数value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch, height, width, channels]这样的shape
        #第二个参数ksize:池化窗口的大小,取一个四维向量,一般是[1, height, width, 1],因为我们不想在batch和channels上做池化,所以这两个维度设为了1
        #第三个参数strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride,stride, 1]
        #第四个参数padding:和卷积类似,可以取'VALID' 或者'SAME'
        #返回一个Tensor,类型不变,shape仍然是[batch, height, width, channels]这种形式

    with tf.variable_scope("layer3-conv2"):
        conv2_weights = tf.get_variable("weight",[5,5,6,16],initializer=tf.truncated_normal_initializer(stddev=0.1))# [5,5,32,64] 5表示本次卷积核高宽,32表示经过上一层32个卷积核的卷积,我们有了32张特征图,64表明本次会有64个卷积核卷积
        conv2_biases = tf.get_variable("bias", [16], initializer=tf.constant_initializer(0.0))
        conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))

    with tf.name_scope("layer4-pool2"):
        pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
        nodes = 8*8*16
        reshaped = tf.reshape(pool2,[-1,nodes])  # 其中pool2是链接上一层,我把pool4和pool3的卷积核池化层删除了,卷的太多都要成渣渣了。
        # tf.reshape(tensor(矩阵),shape(维度),name=None)
        # 改变一个矩阵的维度,可以从多维变到一维,也可以从一维变到多维
        # 其中,-1参数表示不确定,可由函数自己计算出来,原矩阵/一个维度=另一个维度

    with tf.variable_scope('layer9-fc1'):
        fc1_weights = tf.get_variable("weight", [nodes, 1024],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc1_weights))
        # tf.add_to_collection:把变量放入一个集合,把很多变量变成一个列表
        #在深度学习中,通常用这几个函数存放不同层中的权值和偏置参数,
        #也就是把所有可学习参数利用tf.contrib.layers.l2_regularizer(regular_num)(w)得到norm后,都放到’regular’的列表中作为正则项,
        #然后使用tf.add_n函数将他们和原本的loss相加,得到含有正则的loss。
        fc1_biases = tf.get_variable("bias", [1024], initializer=tf.constant_initializer(0.1))

        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases) # MCP模型
        if train: fc1 = tf.nn.dropout(fc1, 0.5) #tf.nn.dropout是TensorFlow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层。

        # tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None,name=None) 
        # 上面方法中常用的是前两个参数:
        # 第一个参数x:指输入的数据。
        # 第二个参数keep_prob: 设置神经元被选中的概率,在初始化时keep_prob是一个占位符,  keep_prob = tf.placeholder(tf.float32) 。
        # tensorflow在run时设置keep_prob具体的值,例如keep_prob: 0.5
        # 第五个参数name:指定该操作的名字。


    with tf.variable_scope('layer10-fc2'):
        fc2_weights = tf.get_variable("weight", [1024, 512],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc2_weights))
        fc2_biases = tf.get_variable("bias", [512], initializer=tf.constant_initializer(0.1))

        fc2 = tf.nn.relu(tf.matmul(fc1, fc2_weights) + fc2_biases)
        if train: fc2 = tf.nn.dropout(fc2, 0.5)

    with tf.variable_scope('layer11-fc3'):
        fc3_weights = tf.get_variable("weight", [512, 5],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer != None: tf.add_to_collection('losses', regularizer(fc3_weights))
        fc3_biases = tf.get_variable("bias", [5], initializer=tf.constant_initializer(0.1))
        logit = tf.matmul(fc2, fc3_weights) + fc3_biases
#        variable_summaries(fc3_weights)
#        variable_summaries(fc3_biases)

    return logit





# 设置超参
path = "E:\\study\\MINST-PLUS\\data" #样本路径
data_size = [32,32,3]                #样本大小和通道数
data_ratio = 0.9   # 百分之多少用于训练,剩下的用于测试
is_train = False
epoch = 1           # 训练次数
batch_size = 1      # 每次训练多少



# 样本和标签的读入与分类
data,label = read_img(path,data_size)
x_train,y_train,x_val,y_val = data_split_flow(data,label,data_ratio)

# 为数据与标签设立两个存放空间
x = tf.placeholder(tf.float32,shape=[None,data_size[0],data_size[1],data_size[2]],name = 'x')
y_ = tf.placeholder(tf.int32,shape=[None,],name = 'y_')

# 定义规则化方法,并计算网络激活值
regularizer = tf.contrib.layers.l2_regularizer(0.0001)   # 过拟合与正则化(regularizer),这个regularizer就是inference函数的最后一个参数。
#两种思想都是希望限制权重的大小,使得模型不能拟合训练数据中的随机噪点。(两种思想,就是两个公式,因为是图,就没贴出来)
#两种方式在TensorFlow中的提供的函数为:
#tf.contrib.layers.l1_regularizer(scale, scope=None) 其中scale为权值(这个权值会乘以w的值,MCP的内个w,江湖传闻w和过拟合值有说不清的关系)
#tf.contrib.layers.l2_regularizer(scale, scope=None)

logits = cnn_fc(x,is_train,regularizer)  #x是输入的图像的tansor,logits是经过卷积、池化、全连接处理处理过的数据

#b = tf.constant(value=1,dtype=tf.float32)  # constant(值、列表 , 数组格式)根据值、列表,生成一个数组,格式为“数组格式”
#logits_eval = tf.multiply(logits,b,name='logits_eval') # 额,不知道这是计算啥


# 计算误差与准确率,并写入日志 (我没有日志,呵呵)
loss = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=logits) #计算logits 和 labels 之间的稀疏softmax 交叉熵 这个是计算误差率
'''
train_op = tf.train.AdamOptimizer(learning_rate=0.01).minimize(loss)  # tf.train.AdamOptimizer 优化器中的梯度优化函数,
# 作用是依据learning_rate步长,来最小化loss误差率。

correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_)
#tf.argmax(vector, 1):返回的是vector中的最大值的索引号,如果vector是一个向量,那就返回一个值,如果是一个矩阵,那就返回一个向量,
#这个向量的每一个维度都是相对应矩阵行的最大值元素的索引号。

# tf.cast(x, dtype, name=None)
# 此函数是类型转换函数
# 参数
# x:输入
# dtype:转换目标类型
# name:名称
# 返回:Tensor

# tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,
# 返回的值的矩阵维度和A是一样的,返回的也是一个矩阵、向量、列表,里面都是true和false。

#这一行的意思,大概是,通过以上三个函数,对比处理后的logits值和labels值,然后得出一个判断表单

acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) #这个......大概是在计算准确率
# 求平均值tf.reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)
# 参数1--input_tensor:待求值的tensor。
# 参数2--reduction_indices:在哪一维上求解。
# 参数(3)(4)可忽略

# tf.summary.scalar('accuracy', acc)

'''

# 创建保存点,并进入计算图流程   还有限制gpu,我的电脑没有这句话就各种死

#saver=tf.train.Saver()
sess=tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True))  #限制gpu内存
sess.run(tf.global_variables_initializer())   # 全世界get_variable嗨起来

for epoch in range(epoch):   # 训练多少遍,epoch是用户输入的,比如是5,也就是把样本遍历5遍
    start_time = time.time()       # 开始计时

    ### 单次训练部分  此处for循环结束之日,就是训练样本遍历了一遍之时......
#    train_loss, train_acc, n_batch = 0, 0, 0    # 先定义下训练误差,训练识别率,训练批次
    for x_train_a, y_train_a in minibatches(x_train, y_train,batch_size, shuffle=False):  
    #遍历minibatches函数,因为这个函数中有yield关键字,每次for,会获取到不同的批次,直到训练样本集合身体被掏空。注意,这里shuffle为True,样本是随机的。
        log,los = sess.run([logits,loss], feed_dict={x: x_train_a, y_: y_train_a})  #向sess.run中喂数据,
        # 其中merged是train_summary计算图;train_op是梯度优化方法,err接收的loss是误差率;ac接收的acc是准确率。后面的x和y_就是每批的数据和标签。
#        train_loss += err; train_acc += ac; n_batch += 1  #统计误差率、准确率、批次
        print(log,los)  #输出每个样本的logits值和loss值
    print()
    print()



sess.close()

然后这个是160个样本的logits值和loss值的对应:

[[ -339.9708     -69.041725 -1067.7036    -245.84515    138.52219 ]] nan
[[-158.06973 -246.89626 -935.557   -248.51776  103.3337 ]] 0.0
[[ -155.45343  -174.68727 -1113.9407   -227.96527   162.82603]] nan
[[ -217.28845  -243.36374 -1009.486    -198.31784   119.12733]] 336.41577
[[-236.27396 -133.29968 -883.61383 -307.63428  185.67291]] nan
[[-149.70811 -132.09709 -886.4549  -129.16461  140.89886]] nan
[[-115.13487 -173.27644 -987.3448  -254.20341  218.48964]] nan
[[-326.896   -308.39993 -914.8617  -134.75952  150.18616]] 1065.0479
[[-473.68124 -214.30078 -982.75653 -324.08688  253.72874]] 0.0
[[-180.8921   -145.02092  -742.64105  -172.11078   -16.130255]] 164.76186
[[ -225.14946  -161.39912 -1025.3687   -318.29987   178.14491]] nan
[[-205.64194 -327.26382 -957.71124 -138.00604   41.8925 ]] 369.1563
[[ -200.25946  -217.56631 -1017.56995  -153.5807     88.18885]] nan
[[ -114.34741  -286.7671  -1103.8845    -76.43528   187.08517]] nan
[[-191.44543  -254.11757  -897.7715    -71.173195   40.45874 ]] 0.0
[[ -210.87175  -183.36429 -1189.2098   -205.37778   193.08887]] nan
[[-296.5331  -314.5609  -943.02246 -319.9631   147.95262]] 462.51355
[[ -225.04294  -188.95775 -1016.372     -78.7354    121.46053]] 346.50348
[[-397.52747 -244.8122  -997.7895  -298.903    158.88753]] 1156.677
[[-197.89807 -306.24576 -971.24677 -268.07953  151.33243]] 419.41196
[[-124.87983  -265.53268  -998.7135   -178.9643     40.895084]] nan
[[ -189.38452   -101.057785 -1135.6907    -245.18817    169.72134 ]] nan
[[ -208.67839   -97.87629 -1034.4067   -319.19882   201.7934 ]] nan
[[-303.44107 -331.08414 -957.3063  -255.90576  -71.63695]] 231.80412
[[ -169.57759  -108.55869 -1209.5519   -172.89476   208.19168]] nan
[[-147.5819   -171.07469  -910.13245   -82.26827    86.733116]] nan
[[ -114.29173  -207.91628 -1032.6654   -252.88803   140.07599]] 392.96402
[[ -262.4568   -229.78604 -1120.4459   -311.7682    114.07547]] 1234.5214
[[ -98.569    -274.89136  -851.79877  -175.66774    44.803627]] 319.69498
[[-203.76027  -314.2957   -964.86017  -179.71866    93.350426]] 297.1107
[[ -343.4648    -87.47349 -1003.65076  -229.2045     93.31492]] nan
[[-306.13544 -275.4731  -985.6897  -212.52412  229.50276]] 1215.1925
[[-246.24588 -172.22351 -979.2212  -365.32474  167.35965]] nan
[[ -171.15607  -185.04291 -1040.1666   -321.16483   158.0437 ]] nan
[[ -242.58545  -276.06787 -1102.614    -254.65155    33.01659]] 1135.6306
[[-319.27502 -255.60544 -993.10474 -222.13464  102.73994]] nan
[[ -232.80014  -169.73009 -1049.5348   -278.7196    106.64243]] 0.0
[[ -283.4286    -265.5071   -1080.9565    -135.41049     25.358812]] 1106.3153
[[-254.03354 -245.81119 -897.9285  -151.69801  283.48123]] 1181.4098
[[-237.50143 -108.99458 -999.13116  -57.81022  129.1613 ]] nan
[[  -84.78888   -357.9854   -1021.0631    -124.382515    80.317085]] nan
[[ -104.82024  -155.68355 -1069.089    -103.73483   162.18747]] nan
[[ -353.33444  -256.59726 -1091.0883   -189.24574   163.08266]] nan
[[ -281.48697   -268.96808  -1089.013     -215.51926    111.097404]] 0.0
[[ -108.74593   -207.82924  -1022.5798      30.671427   158.44952 ]] nan
[[ -270.25153    -91.86211  -1038.885      -70.766365    56.55582 ]] nan
[[  -90.15577  -236.79808 -1031.4894    -59.98573   141.76393]] nan
[[ -311.74524  -208.38995 -1106.2184   -265.01407   143.67767]] 408.69174
[[ -283.07996  -334.26627 -1017.7294     75.00644   113.51844]] nan
[[ -84.62168  -215.93942  -877.76      -42.796043  117.19004 ]] 333.12946
[[ -444.87115   -155.75624  -1000.6751    -274.3312      67.391396]] nan
[[-175.6055  -177.45187 -956.40845 -208.07755  193.24405]] nan
[[-127.719536 -118.41273  -910.33307   -57.89358   225.84187 ]] nan
[[-160.2211  -359.9434  -950.14905 -383.40866   68.7264 ]] 228.94751
[[ -330.75717  -221.13495 -1126.4286   -249.4523    157.82033]] 0.0
[[ -317.854    -216.11125 -1124.4321   -333.89658    72.02384]] 0.0
[[ -145.76814  -164.05063 -1070.6409   -265.389     158.17354]] nan
[[-458.3488  -110.30086 -729.96893 -174.44748  123.08376]] nan
[[ -260.35175    -85.30303  -1038.1746     -88.20037     43.203064]] nan
[[-193.7908  -178.48108 -976.34186 -147.9273    71.281  ]] nan
[[-160.45596 -227.0351  -980.53204 -257.40555  136.3117 ]] 363.3468
[[-324.96848 -250.75949 -905.21655 -237.44872  126.95617]] 451.92465
[[-255.43643 -144.47112 -981.6728  -277.40518   89.83526]] nan
[[-294.73996 -201.05695 -934.9142  -212.22504   92.31458]] 304.5396
[[  -60.04465   -304.3467   -1003.30566   -128.80835     11.641184]] 140.44954
[[ -269.05557   -56.25332 -1023.58856  -270.5889     89.06655]] 1112.6552
[[ -201.44669    -56.80385  -1069.413     -111.28465     93.723366]] nan
[[-270.17545  -188.53314  -881.24005   -50.640648   41.741005]] nan
[[-321.01257 -171.03114 -892.8456  -263.67923  244.1175 ]] 507.79672
[[-209.63803 -237.64368 -965.5896  -126.93542   60.0495 ]] 269.68753
[[ -160.52185  -309.55972 -1023.54205  -234.4269    112.4087 ]] 1135.9508
[[-123.671295 -137.8548   -963.54065  -226.66035   198.14719 ]] nan
[[-302.33188 -120.44096 -839.5305   -93.5154   260.22638]] nan
[[-220.99509  -402.36282  -830.12946  -159.62068   -33.288696]] nan
[[-129.90877  -233.7623   -940.3112   -273.95605    88.052765]] 321.81506
[[ -188.98926   -109.18145  -1062.928     -216.86032    -42.975616]] 173.8847
[[-249.33327  -126.364204 -944.26166  -182.81226    81.48772 ]] 207.85193
[[-275.5864  -179.4247  -838.4203  -175.84933  127.97401]] 307.3987
[[-233.9021  -167.8511  -923.41077 -338.71536  105.40717]] 339.30927
[[-154.15067 -219.50787 -932.8594  -172.86     145.23627]] nan
[[-336.6325  -150.86961 -987.45844 -416.67773  100.29595]] nan
[[-109.250435 -255.91937  -942.4339   -250.14264    65.2409  ]] 174.49133
[[-329.03146 -136.05432 -906.2349  -125.78969  151.86719]] nan
[[-182.69543 -117.93092 -887.67596 -150.77579  246.93314]] nan
[[-215.27608 -239.18161 -951.6927  -276.07352   81.45347]] 0.0
[[-249.49655 -160.32976 -929.5558  -210.60397  169.61095]] nan
[[-185.3315  -161.3625  -981.8229  -218.26953   64.89188]] 226.25438
[[-197.7729  -246.95831 -885.067   -159.57289   70.80913]] 268.58203
[[ -247.88788   -243.84164  -1041.2776    -223.2274       8.276247]] 231.50365
[[-116.093796 -252.39029  -975.2815   -179.439      55.200832]] nan
[[ -304.23566  -206.13531 -1021.2298   -279.1876    134.5904 ]] 0.0
[[ -167.41505  -290.02722 -1088.9889   -289.79114   108.8773 ]] nan
[[-113.61386 -177.24016 -978.99646 -186.46254  166.15945]] nan
[[-214.9445  -274.57474 -989.94257 -252.67047   76.80788]] 1066.7505
[[-328.99948 -142.98679 -890.17926  -47.91146  187.42532]] 235.33679
[[-318.05435 -234.34946 -974.4692  -371.42282  197.50917]] nan
[[-322.47925  -296.4612   -786.0366   -260.93814    34.689926]] 295.62805
[[-260.98065 -139.0556  -979.7749  -236.01236   89.39515]] 325.4075
[[ -216.47476   -242.94846  -1187.5851     -35.244865   203.28448 ]] nan
[[-253.9298  -226.44232 -873.02203 -313.8972   105.37617]] 359.30597
[[ -263.8229     -85.59185  -1027.0349    -188.05847     70.127914]] 0.0
[[-226.96455  -350.6143   -934.15424  -403.949     107.345406]] 0.0
[[ -225.16797  -224.32045 -1024.6873   -260.6547    145.33766]] nan
[[-214.15053 -180.1033  -961.72723 -131.94563  187.9061 ]] nan
[[-205.15431  -90.35216 -985.7997   -97.81426  296.0572 ]] nan
[[  -39.692696  -179.84854  -1010.374     -235.89621    149.93866 ]] 0.0
[[ -137.29457  -247.16678 -1044.9868   -214.56812   208.8024 ]] nan
[[-226.80487 -257.542   -807.0806   -94.40583  134.44495]] nan
[[-335.67172 -296.20285 -977.98224 -299.2244    93.04832]] 392.2727
[[-357.93008  -158.42532  -981.5487    -94.079735  106.91116 ]] 265.3365
[[-180.33228 -319.61642 -919.0159  -175.70108   41.46098]] 0.0
[[-204.44574 -176.60248 -915.4153  -192.80743  248.07481]] nan
[[ -207.401    -240.58766 -1143.0149   -223.05054   222.62633]] 445.67688
[[ -78.20231 -170.62965 -929.0462  -140.9888   164.95868]] nan
[[-245.6157   -229.46317  -842.87885  -220.72922   -35.260365]] 0.0
[[ -155.18925   -336.91263  -1029.1163    -134.4563     121.586395]] nan
[[-306.16397  -302.93027  -940.0308    -23.452402  144.93509 ]] nan
[[ -347.27948  -183.66106 -1070.1736   -200.30228   202.54492]] 1272.7185
[[ -447.05988  -247.93839 -1062.3512   -281.13254   213.68864]] nan
[[  -70.152466  -185.43758  -1200.9169     -75.4078      50.66443 ]] nan
[[ -274.66092  -167.53142 -1038.9081    -65.69486   194.3028 ]] nan
[[-266.57123 -282.13956 -971.00305 -242.11621  261.3142 ]] nan
[[ -100.10769  -193.23499 -1145.0785   -251.36806   127.34045]] nan
[[-319.1334  -133.14326 -968.18585 -177.7191   113.3699 ]] 246.51317
[[-236.21024 -318.41287 -931.91626 -239.98425  177.49658]] 1109.4128
[[-148.49323 -153.51778 -949.8595  -186.73     234.32515]] nan
[[-287.29272 -262.0836  -942.91266 -289.51947   72.3741 ]] 359.6668
[[ -177.96896  -257.7658  -1041.6185   -247.08409   245.98547]] 1287.604
[[-189.93631 -134.58589 -961.63763 -227.20844   73.72845]] 208.31433
[[-278.43698 -301.71268 -987.395   -256.13446  133.51884]] 435.2315
[[ -38.682915 -241.96428  -952.77966  -237.89127   184.73463 ]] nan
[[ -210.01418   -251.97113  -1068.6212    -161.34848     18.539766]] nan
[[ -415.796     -180.30093  -1048.6417    -244.92451    -10.242754]] nan
[[-330.75082  -109.409935 -931.47253  -175.08443   136.03618 ]] nan
[[-372.4756  -209.88126 -946.16864 -282.48892  213.54062]] 0.0
[[-290.56567 -232.0031  -903.3796  -203.44987  136.8045 ]] nan
[[ -168.237      -48.51886  -1007.57196   -268.30103      8.270384]] 276.5714
[[-190.16563  -293.66812  -961.18677  -210.72351    43.457767]] 337.1259
[[-121.66906  -97.86895 -949.0519  -296.6742   292.42038]] nan
[[-275.50165  -305.2471   -905.8998   -237.31598     5.080255]] 280.5819
[[-265.09814   -10.732046 -934.89746   -99.4004     99.830315]] nan
[[-203.9502  -214.38405 -973.2294  -207.28487  199.57446]] 406.8593
[[-119.02307  -70.20489 -993.96533  -60.46907  133.52333]] nan
[[  -93.23775   -238.86374  -1000.00287    -62.871506   194.55057 ]] nan
[[-354.1185  -160.57971 -997.72955 -248.8676   110.5924 ]] nan
[[ -92.723495 -188.39053  -934.18945  -232.07838    98.58349 ]] 1032.773
[[ -150.3228   -221.97133 -1024.3047    -94.51653   153.2828 ]] 1177.5875
[[-289.7434  -160.13202 -968.046   -247.3945    81.17593]] 1049.2219
[[ -206.62665  -325.7108  -1054.6017   -302.03802   128.78539]] 0.0
[[ -172.194      -194.68945   -1003.4911     -134.32576      -7.0236497]] 165.17035
[[  -70.582756  -176.99881  -1013.3966    -218.64465    172.52576 ]] nan
[[-231.41248 -177.90192 -922.4085  -169.71332  173.9874 ]] 405.39987
[[ -219.94849   -249.04947  -1112.8917     -45.301296    89.638374]] nan
[[-134.35938 -235.0812  -930.05457 -135.55515   69.22712]] 304.30832
[[-320.70508 -192.43839 -731.29553 -123.40485  178.42178]] nan
[[ -250.931    -188.67175 -1186.5266   -191.62384    99.96313]] nan
[[ -147.64577   -110.634346 -1069.9188    -222.07056    173.16571 ]] nan
[[ -403.27338  -278.92044 -1039.2247   -235.52284    68.27099]] nan
[[-251.42561 -181.8896  -859.71875 -204.08308  109.86707]] 313.95016
[[-242.54707  -114.25371  -898.86566  -202.8183     97.452736]] 211.70645

前面是logits值,后面跟的是loss值。

在偷窥、盗摄、观望了一票大神的博客后,可能是网络模型的问题,不过我感觉应该是样本的问题,因为样本是我自己剪切出来的……..会不会就是神仙们说的:有脏数据…….

样本集下载地址:https://download.csdn.net/download/gaoyue5511/10644624 这个怎么设置下载不要分,大神在评论下发一下。或者您可以留下邮箱我发送过去。

亲人们,经过老师的提点,让我一并输入y_值(也就是训练标签值)。我发现,我的分类是10种,也就是0-9,而我copy的代码,他之前的分类是5种(捂脸,捂脸)……..所以,原代码的logits输出是有5个,代表5种可能性。而我忘记改了(捂脸,捂脸)。。。。。。所以,你们可以看到,标签大于4的loss值,都是nan…………

我感觉这篇博客像个耻辱柱………
我想把它删掉,让遇到这个坑的人都陷入万劫不复的境地…….

你可能感兴趣的:(人工智障)