Keras train_on_batch行为

时间:2018-10-12 18:24:38

标签: python tensorflow machine-learning keras

注意。 Python 3.5版

我已经在简单的Keras模型和Tensorflow模型中复制了此问题,如下所示。

from keras.layers import Dense, Input
from keras.models import Model
from keras.optimizers import Adam
import keras
import keras.backend as K


import numpy as np
import tensorflow as tf


class KerasModel(object):
    def __init__(self, seed, dim_size, optimizer, loss_func):

        I = Input(
            shape=[dim_size], 
            name='i'
                 )

        O = Dense(
            1,
            activation='relu',
            kernel_initializer=keras.initializers.glorot_uniform(seed=seed),
            name='o'
                 )(I)


        self.model = Model(inputs=I,outputs=O)
        self.model.compile(loss=loss_func, optimizer=optimizer)


class TFModel(object):
    def __init__(self, seed, dim_size, optimizer, loss_func):

        self.graph= tf.Graph()

        with self.graph.as_default():
            glorot_uniform= tf.glorot_uniform_initializer(seed=seed)

            O= {
                    'weights': tf.Variable(glorot_uniform([dim_size, 1])),
                    'bias': tf.Variable( tf.zeros(1) )
                }


            w_list= [ 
            O['weights'], O['bias']
                        ] 

            w_list_placeholder= []
            w_list_update= []

            for i in range(0, len(w_list)):
                w_list_placeholder.append( tf.placeholder(tf.float32) )
                w_list_update.append( w_list[i].assign( w_list_placeholder[i] ) )


            I= tf.placeholder(tf.float32, shape= (None, dim_size))

            output= tf.nn.relu( tf.add( tf.matmul( I, O['weights']), O['bias'] ) )

            y= tf.placeholder(tf.float32)

            loss= tf.reduce_mean( loss_func(y, output) )

            train = optimizer.minimize(loss)

            self.tensors= {
                'output': output, 'I': I, 'y': y, 
                'loss': loss, 'train-op': train, 'w': w_list,
                'w-placeholder': w_list_placeholder, 'w-update': w_list_update
                          }

            self.sess= tf.Session(graph=self.graph)

            self.sess.run( tf.variables_initializer( self.graph.get_collection('variables') ) )


    def train_on_batch(self, X, y):
        _, l=self.sess.run( 
            [ self.tensors['train-op'], self.tensors['loss'] ],
            feed_dict={ 
                self.tensors['I']: X,
                self.tensors['y']: y
                       }
                           )
        return l

    def predict(self, X):
        return self.sess.run(self.tensors['output'], feed_dict={self.tensors['I']: X})

    def get_weights(self):
        return self.sess.run(self.tensors['w'])

    def set_weights(self, new_weights):
        self.sess.run( self.tensors['w-update'], 
                      feed_dict={ 
                          x:y for x,y in zip(self.tensors['w-placeholder'], new_weights)
                                } 
                     )

我创建了一个test函数,该函数使用相同的优化程序,初始化,损失函数等来初始化模型。然后使用同一批次的训练样本来训练模型,其中训练损失和权重然后比较模型。如下所示:

def test(repeat, samples=1, dim_size=3, seed=1, e=1e-08, learning_rate=0.01):

    k_adam= KerasModel(seed, dim_size, Adam(lr=learning_rate, epsilon= e),
                   keras.losses.mean_squared_error
                  )

    tf_adam= KerasModel(seed, dim_size, tf.train.AdamOptimizer(learning_rate=learning_rate,epsilon= e),
                        keras.losses.mean_squared_error
                       )

    tf_model= TFModel(seed, dim_size, tf.train.AdamOptimizer(learning_rate=learning_rate,epsilon= e),
                      keras.losses.mean_squared_error
                      )

    for _ in range(0,repeat):



        X= np.random.random([samples,dim_size])
        y= np.random.random([samples])

        print(k_adam.model.train_on_batch(X, y))
        print(tf_adam.model.train_on_batch(X, y))
        print( tf_model.train_on_batch(X,y) )

        print()
        print()

        print(k_adam.model.get_weights())
        print(tf_adam.model.get_weights())
        print(tf_model.get_weights())
        print()

我发现当testsamples=1一起运行时,等效于train_on_batch()和1个训练样本。在使用的3种模型中,有时可能会达到相同的训练损失和相同的权重(一开始的可能性更大)。即使训练损失和权重开始有所不同,我也发现tf_adamtf_model始终保持不变。这是有道理的,因为它们是具有相同优化器的相同模型。

但是,当samples以更大的数量运行时,实际上运行多个训练样本的train_on_batch()。训练损失和权重开始有所不同。结果发现,当使用更多的数字时,训练损失和重量的变化也会增加。

train_on_batch()中实际上发生了什么?在Keras的train_on_batch()文档中,没有提到批次之间的混洗行为。但是我的测试表明已经进行了一些改组。否则,当使用同一批次进行训练时,模型应达到相同的训练损失和权重,但仅在使用1个样本时才这样做。

0 个答案:

没有答案