tensorflow小白的全连接神经网络代码分析

从前天开始看tensorflow的介绍视频,觉得一步步慢慢看视频没有直接看代码有效率。于是在网上找来了tensorflow的范例代码进行分析。由于没有什么关于tensorflow的知识基础,在注释中有什么写得不对的地方欢迎各位大佬进行批评。如果觉得我写的还不错请点一个赞,您的支持是我保持不断学习动力的重要支撑!!!谢谢各位

#程序代码来源:https://blog.csdn.net/WuLex/article/details/66972720
import tensorflow as tf
import numpy as np


def make_layer(inputs, in_size, out_size, activate=None):
    #这是一个创建一层神经元的函数,input是什么意思?--input是该层上一层的对象,用于将两层神经元连起来
    #传入输入输出的维度,将激活函数默认设置为没有
    
    weights = tf.Variable(tf.random_normal([in_size, out_size]))
    #input size对应上一层的神经元数加一(偏置项)
    #output size对应本层的神经元数目,输出一个n维的行向量
    
    basis = tf.Variable(tf.zeros([1, out_size]) + 0.1)
    #创建一个1*outputSize的矩阵
    #若output size = 3 生成的是一个[[0.1 0.1 0.1]]
    #为什么这里使用数值0.1而不是新建常量并且用常量进行赋值?
    #--因为每新建一个layer的时候都要调用这一语句,既然都是临时调用进行初始化,只执行一次,就不用为其占用内存了,直接使用临时值进行调用即可
    
    result = tf.matmul(inputs, weights) + basis
    #这里的模型中input与output是一个行向量, weight 是每一列是一个神经元
    #后面加上的一个0.1可能是为了防止函数陷入局部最小值
    
    if activate is None:
        return result
    else:
        return activate(result)
    #激活函数的作用是将每一个输出对应的进行处理,将线性的数据变成非线性的
    ###IMPORTANT:tensorflow的一个作用相当于是将所有默认以值传递的函数改为默认以引用传递,所以最后返回的result是一个含有上面所有操作的op
    #当使用tensorflow调用该result的时候会自动调用所有与其相关的操作
    #更形象的比喻是,在session.run之前的所有语句相当于在组装一个大型的机械系统,不论那条语句在哪个scope其作用都是全局的,
    #而在系统构造阶段的所有函数只是为了节省代码长度而设计的重复调用的模块
    #实际构造的过程是将所有代码根据其运行顺序展开进行的构造


class BPNeuralNetwork:
    def __init__(self):#构造函数
        self.session = tf.Session()
        self.input_layer = None
        self.label_layer = None
        self.loss = None
        self.optimizer = None
        self.layers = []

    def __del__(self):#析构函数
        self.session.close()

    def train(self, cases, labels, limit=100, learn_rate=0.05):
        # 构建网络
        
        self.input_layer = tf.placeholder(tf.float32, [None, 2])
        #创建了一个输入层,不限神经元数目,两列的函数(可以支持二维的训练数据x)
        #实际计算时会将列向量的输入转化为行向量
        
        self.label_layer = tf.placeholder(tf.float32, [None, 1])
        #创建一个目标向量层,不限制神经元数目,一层输出,其的值是一个n维的向量,是每一个输入X对应的target Y
        
        self.layers.append(make_layer(self.input_layer, 2, 10, activate=tf.nn.relu))
        #创建一个隐藏层,输入的维数是2,输出的维数是10,将它与输入层连起来
        
        self.layers.append(make_layer(self.layers[0], 10, 2, activate=None))
        #创建一个输出层,输入的维数是10,输出的维数是2,将它与第一隐藏层连起来,输出的二维向量就是预测的结果^y
        
        self.loss = tf.reduce_mean(tf.reduce_sum(tf.square((self.label_layer - self.layers[1])), reduction_indices=[1]))
        #定义损失函数:loss = mean(sum((...)^2))  差的平方的和的平均数 -- Mean Square Loss
        #一共两层,不算输入的话,所以layer[1]就是输出层就是layer[-1]
        #为什么输出明明只有一维却建立了两位的输出向量???
        #reduction_indices=[1]?????
        
        self.optimizer = tf.train.GradientDescentOptimizer(learn_rate).minimize(self.loss)
        #tensorflow中自带的优化器,梯度下降优化器,需要设置其学习率,以及最小化的函数对象
        
        initer = tf.initialize_all_variables()
        self.session.run(initer)
        #tensorflow要求所有变量必须在运行前进行初始化--这是一个纠错的好机会,如果不使用global_initializor 代码编写者根据自己脑海中构建的模型进行选择性初始化可以
        #确定有没有不在预期之中的变量或者是数据结构
        
        
        # 做训练
        for i in range(limit):
            self.session.run(self.optimizer, feed_dict={self.input_layer: cases, self.label_layer: labels})
            #每运行一次梯度下降就优化一部分

    def predict(self, case):
        #在测试环节使用的预测函数,用于输出预测值
        return self.session.run(self.layers[-1], feed_dict={self.input_layer: case})
        #list[-1]是指list中的最后一个元素,并且调用训练好的网络进行输出
        #“使用make_layer为神经网络定义两个隐含层, 并用最后一层作为输出层:”
    

    def test(self):
        #用于测试模型
        
        x_data = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
        y_data = np.array([[0, 1, 1, 0]]).transpose()
        #transpose 资料:https://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html
        #矩阵的转置
        #创建测试所需要的测试集--一个抑或问题
        #[0,0,   0]
        #[0,1,   1]
        #[1,0,   1]
        #[1,1,   0]
        
        test_data = np.array([[0, 1]])
        self.train(x_data, y_data)
        #调用四个数据的数据集进行训练
        
        print(self.predict(test_data))
        #打印预测结果

#void main():
nn = BPNeuralNetwork()
#创建神经网络的对象

nn.test()
#训练并且测试神经网络的精确度并且打印出预测值

predict output:[[0.99249804 0.916942 ]]

由于我没有python面向对象编程的基础,所以边分析边学习,其中的一些问题希望各位大佬可以指出,谢谢

#程序来自:菜鸟教程 python 面向对象编程
Python中类的写法:
##注意,python中的成员变量是散放在各个函数之中的, 较好的书写方式是将所有成员变量集中在__init__中???

class Employee:
   '所有员工的基类'----------------------类的帮助,自动以字符串的形式编写,不需要注释
   empCount = 0------------------所有类成员共享的变量,
   #相当于public static?  并且可以在类之外访问 有点像但是类变量在生成对象之后就跟随对象改变,相当于这是一个类的全局促初始化常量?
    
   def __init__(self, name, salary):------构造函数
      self.name = name-------名称前没有__的是public属性 有__是private 单下划线是protect 成员函数也是一样的定义方式
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount
 
   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值