梯度不下降怎么辦?欠擬合的解決方案

在網(wǎng)絡(luò)上查閱很多擬合曲線的示例后發(fā)現(xiàn),絕大部分都在用平方差(tf.square)作為曲線擬合的loss,從這點(diǎn)深入搜索后發(fā)現(xiàn),平方差(tf.square)幾乎就是曲線擬合最合理的loss,不管是從適應(yīng)面上、還是從數(shù)學(xué)原理上。并且tensorflow還整合的平方差(tf.square)和平均值(tf.reduce_sum)的整合函數(shù)(tf.losses.mean_squared_error)。于是我把loss修改為如下:

loss = tf.losses.mean_squared_error(labels=y_, predictions=y)

但是這樣就又回到了最開始的樣子,loss總是無意義的躁動(dòng)。

在觀察了生成的y值之后發(fā)現(xiàn),竟然只有前幾次生成的y值是非0的,在進(jìn)行了幾次梯度下降后,y值竟然穩(wěn)定在0上,這么說來梯度也消失了。

生成的y值與真實(shí)值的比較

梯度消失。

查閱資料發(fā)現(xiàn),欠擬合和梯度消失有如下幾個(gè)可能:

1.權(quán)重初始化有問題,只使用了簡(jiǎn)單的random而沒有讓其科學(xué)的生成隨機(jī)值,會(huì)造成梯度下降過程中梯度消失

2.神經(jīng)網(wǎng)絡(luò)層數(shù)太深,過深的神經(jīng)網(wǎng)絡(luò)會(huì)造成前幾層神經(jīng)網(wǎng)絡(luò)上的神經(jīng)元學(xué)習(xí)的東西過少,進(jìn)而導(dǎo)致權(quán)重變化慢,造成了梯度不下降的現(xiàn)象

于是,我先嘗試減少幾層神經(jīng)層。

其實(shí)我在訓(xùn)練過程中,曾經(jīng)為了解決loss不下降的問題時(shí)想當(dāng)然的增加過幾層神經(jīng)層,當(dāng)最大增加到第6層時(shí)會(huì)出現(xiàn)偶發(fā)性的訓(xùn)練出錯(cuò)的現(xiàn)象。增加到第10層時(shí)妥妥的每次都報(bào)錯(cuò)。查閱后發(fā)現(xiàn)過深的深網(wǎng)絡(luò)又沒有搭配良好的權(quán)重正則化策略會(huì)導(dǎo)致數(shù)學(xué)錯(cuò)誤,不過此知識(shí)點(diǎn)暫時(shí)沒有再深入追究。

正因?yàn)榇?,在?xùn)練時(shí)我都使用3層神經(jīng)網(wǎng)絡(luò)。此時(shí)因?yàn)榘l(fā)現(xiàn)了層數(shù)過深會(huì)導(dǎo)致梯度消失,我遍索性只使用1個(gè)隱藏層。不抱希望的我發(fā)現(xiàn),竟然y值不再穩(wěn)定在0處了。

y值開始波動(dòng)了

目前代碼

import numpy as np

import pandas as pd

import tensorflow as tf

#轉(zhuǎn)為onehot編碼

def turn_onehot(df):

? ? for key in df.columns:

? ? ? ? oneHot = pd.get_dummies(df[key])

? ? ? ? for oneHotKey in oneHot.columns: #防止重名

? ? ? ? ? ? oneHot = oneHot.rename(columns={oneHotKey : key+'_'+str(oneHotKey)})

? ? ? ? df = df.drop(key, axis=1)

? ? ? ? df = df.join(oneHot)

? ? return df

#獲取一批次的數(shù)據(jù)

def get_batch(x_date, y_date, batch):

? ? global pointer

? ? x_date_batch = x_date[pointer:pointer+batch]

? ? y_date_batch = y_date[pointer:pointer+batch]

? ? pointer = pointer + batch

? ? return x_date_batch, y_date_batch

#生成layer

def add_layer(input_num, output_num, x, layer, active=None):

? ? with tf.name_scope('layer'+layer+'/W'+layer):

? ? ? ? W = tf.Variable(tf.random_normal([input_num, output_num]), name='W'+layer)

? ? ? ? tf.summary.histogram('layer'+layer+'/W'+layer, W)

? ? with tf.name_scope('layer'+layer+'/b'+layer):

? ? ? ? b = tf.Variable(tf.zeros([1, output_num])+0.1, name='b'+layer)

? ? ? ? tf.summary.histogram('layer'+layer+'/b'+layer, b)

? ? with tf.name_scope('layer'+layer+'/l'+layer):

? ? ? ? l = active(tf.matmul(x, W)+b) #使用sigmoid激活函數(shù),備用函數(shù)還有relu

? ? ? ? tf.summary.histogram('layer'+layer+'/l'+layer, l)

? ? return l

hiddenDim = 500 #隱藏層神經(jīng)元數(shù)

save_file = './train_model.ckpt'

istrain = True

istensorborad = False

pointer = 0

if istrain:

? ? samples = 2000

? ? batch = 1 #每批次的數(shù)據(jù)輸入數(shù)量

else:

? ? samples = 550

? ? batch = 1 #每批次的數(shù)據(jù)輸入數(shù)量

with tf.name_scope('inputdate-x-y'):

? ? #導(dǎo)入

? ? df = pd.DataFrame(pd.read_csv('GHMX.CSV',header=0))

? ? #產(chǎn)生 y_data 值 (1, n)

? ? y_date = df['number'].values

? ? y_date = y_date.reshape((-1,1))

? ? #產(chǎn)生 x_data 值 (n, 4+12+31+24)

? ? df = df.drop('number', axis=1)

? ? df = turn_onehot(df)

? ? x_data = df.values


###生成神經(jīng)網(wǎng)絡(luò)模型

#占位符

with tf.name_scope('inputs'):

? ? x = tf.placeholder("float", shape=[None, 71], name='x_input')

? ? y_ = tf.placeholder("float", shape=[None, 1], name='y_input')

#生成神經(jīng)網(wǎng)絡(luò)

l1 = add_layer(71, hiddenDim, x, '1', tf.nn.relu)

#l2 = add_layer(hiddenDim, hiddenDim, l1, '2', tf.nn.relu)

#l3 = add_layer(hiddenDim, hiddenDim, l2, '3', tf.nn.relu)

#l4 = add_layer(hiddenDim, hiddenDim, l3, '4', tf.nn.relu)

#l5 = add_layer(hiddenDim, hiddenDim, l4, '5', tf.nn.relu)

#l6 = add_layer(hiddenDim, hiddenDim, l5, '6', tf.nn.relu)

#l7 = add_layer(hiddenDim, hiddenDim, l6, '7', tf.nn.relu)

#l8 = add_layer(hiddenDim, hiddenDim, l7, '8', tf.nn.relu)

#l9 = add_layer(hiddenDim, hiddenDim, l8, '9', tf.nn.relu)

y = add_layer(hiddenDim, 1, l1, '10', tf.nn.relu)

#計(jì)算loss

with tf.name_scope('loss'):

? ? #loss = tf.reduce_mean(tf.reduce_sum(tf.square(y - y_), name='square'), name='loss')? #損失函數(shù),損失不下降,換用別的函數(shù)

? ? #loss = -tf.reduce_sum(y_*tf.log(y))? #損失仍然不下降

? ? #loss = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y,1e-10,1.0)) , name='loss')

? ? loss = tf.losses.mean_squared_error(labels=y_, predictions=y)

? ? tf.summary.scalar('loss', loss)

#梯度下降

with tf.name_scope('train_step'):

? ? train_step = tf.train.GradientDescentOptimizer(0.00005).minimize(loss)

#初始化

init = tf.global_variables_initializer()

sess = tf.Session()

if istensorborad:

? ? merged = tf.summary.merge_all()

? ? writer = tf.summary.FileWriter('logs/', sess.graph)

sess.run(init)

#保存/讀取模型

saver = tf.train.Saver()

if not istrain:

? ? saver.restore(sess, save_file)

for i in range(samples):

? ? x_date_batch, y_date_batch = get_batch(x_data, y_date, batch)

? ? feed_dict = {x: x_date_batch, y_: y_date_batch}

? ? if istrain:

? ? ? ? _, loss_value, y_value, y__value = sess.run((train_step, loss, y, y_), feed_dict=feed_dict)

? ? ? ? #print('y=', y_value, '----ture=', y__value)

? ? ? ? print(loss_value)

? ? else:

? ? ? ? _, test_assess_value = sess.run((loss, test_assess), feed_dict=feed_dict)

? ? ? ? print(test_assess_value)

? ? if istensorborad:

? ? ? ? result = sess.run(merged, feed_dict=feed_dict)

? ? ? ? writer.add_summary(result,i)

#保存模型

if istrain:

? ? saver.save(sess, save_file)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容