卷积神经网络中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) 
  • 19
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值