第一次使用tensorflow编写程序
2017-12-20 17:31
197 查看
最近一直在学习机器学习,看了一段时间的机器学习理论后,买了一本tensorflow实战的书,开始实战:
tensorflow的基本单位是tensor即张量,就是矩阵,可以是多维的矩阵,具体一些概念不在这里解释
尝试使用tensorflow去解决的第一个问题是给一个数,如果这个数是3的倍数,那它属于第一类,如果是5的倍数属于第二类,最开始的想法是用regression乱train一发,结果坏掉了,不能work
这里是产生数据的代码,每个数字产生对应二进制的表示作为网络的输入,如果%3==0则label为[1 0],如果能%5==0则label为[0 1],如果%15==0则label为[1 1],使用这些数据进行regression
训练过程:
虽然train坏了,但是作为第一个程序,还是让我对tensorflow的结构有了一定的了解,比如使用tensorflow的tensor结果进行所有的运算包括加减乘除运算时,是不会真的进行运算的,而直接生成的计算图,使用当调用sess.run时才会真的去进行计算,计算图的形式,相当于保存了计算过程,而不是只保存结果,更新参数的时候,就是需要不断的通过计算过程做类似的运算来求结果。
发现建图的时候,虽然感觉自己建的是一个结点一个结点的神经网络图,但是在tensorflow中,都是使用矩阵(tensor)来表示的,tensorflow中的每个变量都有一个属性trainable,如果创建变量的时候这个属性为true,这个变量就会被tensorflow放在一个专门维护需要更新的数据的位置,每次进行train过程的时候,都会更新这些参数,如果置为false的话,在进行模型的更新的时候则不会更新这个参数,所以矩阵中的参与运算的值都是默认tranable=true,而global_step这种只是用来计算当前更新次数的变量其实不需要进行更新。
后来发现这个应该当做一个分类问题处理,最简单的处理方式应该讲该问题作为4个类的问题,[1 0 0 0]表示既不是3的倍数也不是5的倍数,[0 1 0 0]表示是3的倍数且不是5的倍数,[0 0 1 0]表示是5的倍数且不是3的倍数,[0 0 0 1]表示是15的倍数
正确的完整程序:
上面的程序...在training data上面的准确率大概也只能达到93左右
考虑了是不是网络不够深,不能适配模型,于是把hide layer变成两层,改了一下网络部分的代码,在1层和2层中间添加了1_5表示1.5层
ps:只是添加一个隐含层会导致参数过多的问题,因此将第一个隐含层的结点数从1000改回100,加上第二个隐含层50的结点,让参数的个数不会变化太大
T_T 然而在training data上的准确率没有提高超过百分之1,还是93.几
training data只有不到900组,再多的隐含层应该也没有帮助,感觉或许是learning rate导致模型的拟合不好,机智的使用的Adagrad自适应的方式更新参数
果然。。。在train data上的准确率迅速到达了100%
发现如果更改一下指数递减的更新参数,也可以在训练数据上达到100的准确率
learning_rate = tf.train.exponential_decay(0.1,global_step,2,0.999999,staircase=False)
然后产生1000-1023的testdata数据进行验证
测试数据部分代码
在测试数据上的准确率为95%左右~
-----------------------------------------------OVER--------------------------------------------
tensorflow的基本单位是tensor即张量,就是矩阵,可以是多维的矩阵,具体一些概念不在这里解释
尝试使用tensorflow去解决的第一个问题是给一个数,如果这个数是3的倍数,那它属于第一类,如果是5的倍数属于第二类,最开始的想法是用regression乱train一发,结果坏掉了,不能work
这里是产生数据的代码,每个数字产生对应二进制的表示作为网络的输入,如果%3==0则label为[1 0],如果能%5==0则label为[0 1],如果%15==0则label为[1 1],使用这些数据进行regression
def int2vector(i): ele=[] dim = 10 while (dim != 0): dim = dim - 1 ele.append(i % 2) i = i // 2 return ele def getLabel(x): ele = [] if x % 3 == 0: ele.append(1) else: ele.append(0) if x % 5 == 0: ele.append(1) else: ele.append(0) return ele def getTranData(x,y): for i in range(10,900): y.append(getLabel(i)) x.append(int2vector(i))
训练过程:
def train(): data=[] label=[] getTranData(data,label) x = tf.placeholder(tf.float32,[None,10],name='x-input') y_ = tf.placeholder(tf.float32,[None,2],name='y-output') weight1 = tf.Variable(tf.random_normal([10,1000],stddev=0.1) ) bias1 = tf.Variable(tf.zeros([1000])) weight2 = tf.Variable(tf.random_normal([1000, 2], stddev=0.1)) bias2 = tf.Variable(tf.zeros([2])) hide = tf.nn.relu( tf.matmul( x,weight1 ) + bias1 ) y = tf.matmul(hide,weight2)+bias2 global_step = tf.Variable(0,trainable=False) learning_rate = tf.train.exponential_decay(0.1,global_step,100,0.96,staircase=False) loss = tf.reduce_sum( tf.square(y-y_) ) cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) train_step = tf.train.AdamOptimizer( 0.1 ).minimize(loss, global_step=global_step) with tf.Session() as sess: init_op = tf.global_variables_initializer() sess.run(init_op) for i in range(10000): sess.run(train_step,feed_dict={x:data,y_:label}) if i % 1000 == 0: print( sess.run( loss,feed_dict={x:data,y_:label} )) xx =[] xx.append(int2vector(500)) print(sess.run(global_step)) print( sess.run(y,feed_dict={x:xx}) )loss函数分别使用square error和cross_entropy强行train了,发现使用500来测试结果都坏掉了,更不用使用test_data来训练了
虽然train坏了,但是作为第一个程序,还是让我对tensorflow的结构有了一定的了解,比如使用tensorflow的tensor结果进行所有的运算包括加减乘除运算时,是不会真的进行运算的,而直接生成的计算图,使用当调用sess.run时才会真的去进行计算,计算图的形式,相当于保存了计算过程,而不是只保存结果,更新参数的时候,就是需要不断的通过计算过程做类似的运算来求结果。
发现建图的时候,虽然感觉自己建的是一个结点一个结点的神经网络图,但是在tensorflow中,都是使用矩阵(tensor)来表示的,tensorflow中的每个变量都有一个属性trainable,如果创建变量的时候这个属性为true,这个变量就会被tensorflow放在一个专门维护需要更新的数据的位置,每次进行train过程的时候,都会更新这些参数,如果置为false的话,在进行模型的更新的时候则不会更新这个参数,所以矩阵中的参与运算的值都是默认tranable=true,而global_step这种只是用来计算当前更新次数的变量其实不需要进行更新。
后来发现这个应该当做一个分类问题处理,最简单的处理方式应该讲该问题作为4个类的问题,[1 0 0 0]表示既不是3的倍数也不是5的倍数,[0 1 0 0]表示是3的倍数且不是5的倍数,[0 0 1 0]表示是5的倍数且不是3的倍数,[0 0 0 1]表示是15的倍数
正确的完整程序:
def int2vector(i): ele=[] dim = 10 while (dim != 0): dim = dim - 1 ele.append(i % 2) i = i // 2 return ele def getLabel(x): if x % 15 == 0: return [0,0,0,1] if x % 5 == 0: return [0,0,1,0] if x % 3 == 0: return [0,1,0,0] return [1,0,0,0] def getTranData(x,y): for i in range(10,900): y.append(getLabel(i)) x.append(int2vector(i)) def train(): data=[] label=[] getTranData(data,label) x = tf.placeholder(tf.float32,[None,10],name='x-input') y_ = tf.placeholder(tf.float32,[None,4],name='y-output') weight1 = tf.Variable(tf.random_normal([10,1000],stddev=0.1) ) bias1 = tf.Variable(tf.zeros([1000])) weight2 = tf.Variable(tf.random_normal([1000, 4], stddev=0.1)) bias2 = tf.Variable(tf.zeros([4])) hide = tf.nn.relu( tf.matmul( x,weight1 ) + bias1 ) y = tf.matmul(hide,weight2)+bias2 global_step = tf.Variable(0,trainable=False) learning_rate = tf.train.exponential_decay(0.1,global_step,100,0.96,staircase=False) loss = tf.reduce_sum( tf.square(y-y_) ) loss2 =tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y,labels=y_)) cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss2,global_step=global_step) correct_prediction = tf.equal( tf.argmax(y,1) , tf.argmax(y_,1) ) accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) with tf.Session() as sess: init_op = tf.global_variables_initializer() sess.run(init_op) for i in range(10000): sess.run(train_step,feed_dict={x:data,y_:label}) if i % 1000 == 0: #每1000次训练打印一下在training data上的 loss和准确率 print( sess.run( loss2,feed_dict={x:data,y_:label} )) print(sess.run(accuracy, feed_dict={x: data, y_: label})*100,'%') print('hide.name = ',hide.name) xx =[] xx.append(int2vector(1000)) #使用training data上没有的1000这个数来测试一下准确率 print( sess.run(y,feed_dict={x:xx}) ) saver = tf.train.Saver() saver.save(sess,"F:/machineLearning/testtensorflow/data.ckpt") #保存网络结果 if __name__ == "__main__": train()
上面的程序...在training data上面的准确率大概也只能达到93左右
考虑了是不是网络不够深,不能适配模型,于是把hide layer变成两层,改了一下网络部分的代码,在1层和2层中间添加了1_5表示1.5层
ps:只是添加一个隐含层会导致参数过多的问题,因此将第一个隐含层的结点数从1000改回100,加上第二个隐含层50的结点,让参数的个数不会变化太大
x = tf.placeholder(tf.float32, [None, 10], name='x-input') y_ = tf.placeholder(tf.float32, [None, 4], name='y-output') weight1 = tf.Variable(tf.random_normal([10, 100], stddev=0.1)) bias1 = tf.Variable(tf.zeros([100])) weight1_5 = tf.Variable(tf.random_normal([100, 50], stddev=0.1)) #添加了一个隐含层 bias1_5 = tf.Variable(tf.zeros([50])) weight2 = tf.Variable(tf.random_normal([50, 4], stddev=0.1)) bias2 = tf.Variable(tf.zeros([4])) hide = tf.nn.relu(tf.matmul(x, weight1) + bias1) hide2 = tf.nn.relu(tf.matmul(hide, weight1_5) + bias1_5) y = tf.matmul(hide2, weight2) + bias2
T_T 然而在training data上的准确率没有提高超过百分之1,还是93.几
training data只有不到900组,再多的隐含层应该也没有帮助,感觉或许是learning rate导致模型的拟合不好,机智的使用的Adagrad自适应的方式更新参数
train_step = tf.train.AdagradOptimizer( 0.1 ).minimize(loss2, global_step=global_step)
果然。。。在train data上的准确率迅速到达了100%
发现如果更改一下指数递减的更新参数,也可以在训练数据上达到100的准确率
learning_rate = tf.train.exponential_decay(0.1,global_step,2,0.999999,staircase=False)
然后产生1000-1023的testdata数据进行验证
def getTranData(x,y,start=10,end=900): #改了一下之前的函数,方便测试数据 for i in range(start,end): y.append(getLabel(i)) x.append(int2vector(i))
测试数据部分代码
test_data = [] test_label = [] getTranData(test_data,test_label,1000,1023) print(sess.run(accuracy, feed_dict={x: test_data,y_:test_label}))
在测试数据上的准确率为95%左右~
-----------------------------------------------OVER--------------------------------------------
相关文章推荐
- 使用TensorFlow编写识别数字的CNN训练程序详解
- 第一次使用linux并编写了一个dump mysql的程序,记录下简单的步骤
- 第一次尝试使用JAVA编写的ATM机程序
- 如何使用Junit编写和组织测试程序
- VC++下使用ADO编写数据库程序
- VC++下使用ADO编写数据库程序
- 不使用Web服务器编写SOAP服务程序相关联接
- 使用JAVA编写网络通信程序
- 使用CppUnit编写测试程序
- 使用eclipse编写hibernate程序 (alluser的专栏)
- 学习API HOOK,编写了一个winsock 的封包抓取程序,可免费使用;
- 使用C#编写的一个定时关机程序
- Linux下,使用C/C++编写一个简单的消息处理程序
- 可启动程序编写环境的搭建和使用
- 使用C#编写不同的"Hello World"程序(转)
- 使用JAVA编写网络通信程序
- VC++下使用ADO编写数据库程序
- mono:直接使用MSIL指令编写mono程序
- 使用C#编写的一个定时关机程序(我也不记得是谁写的了,偶翻出来了就贴了)
- [原创]使用Visual Studio .NET编写纯C程序的提示