tensorflow線形回帰を実現


文書ディレクトリ
  • 計算図
  • 正規化
  • 勾配降下
  • を実現
  • 手動勾配降下
  • 自動微分
  • 小ロット勾配降下
  • 保存モデル
  • tensorflowを用いて線形回帰プログラムを実現し,tensorflowのいくつかの基本動作を簡単に理解した.一部のコードソース:『機械学習実戦Scikit-LiarnとTensorFlowに基づく』
    けいさん図
    tensorflowの本質はPythonで計算図を構築し,最適化されたC++コードでこの図を実行することであるため,大型機械学習や分散計算に適している.図を作成します.
    import tensorflow as tf
    #    
    x=tf.Variable(3,name='x')
    y=tf.Variable(4,name='y')
    f=x*x+x+y+2
    
    # 1
    sess=tf.Session()
    sess.run(x.initializer)
    sess.run(y.initializer)
    result=sess.run(f)
    print(result)
    
    # 2
    with tf.Session() as sess:
        x.initialzer.run()
        y.initialzer.run()
        result=f.eval()
    
    # 3
    init=tf.global_variables_initializer() # prepare an init node
    
    with tf.Session() as sess:
        init.run() # actually run
        result=f.eval()
    
    # 4 
    sess=tf.InteractiveSession() # change to defalut sess
    init.run()
    result=f.eval()
    sess.close()
    

    図を作成する方法は4つあります.
  • 面倒な方法で、一つ一つ手動で.run()
  • withブロックを使用し、
  • をタイムリーに閉じることができます.
  • グローバル変数
  • と3は似ていますが、異なる場所ではsessを手動で閉じるには、この図をデフォルト図に設定します.

  • しかし実際の運用シーンでは,1つまたは複数の特定の計算ノードのみを呼び出し,tfは依存する他のノードを自分でチェックして計算することが多い.ノードの値は保存されないことに注意してください.これは、ノードが同じサーバにいない可能性があるため、分散計算の考え方にも合っています.保存する場合は変数として保存する必要があります.変数はセッションメンテナンスの状態です.(セッション間も分離)
    正規化
    コードを検証する前に、まずデータセットを正規化します.ここでは、[0,1]区間にデータを投じる一般的な線形変換を採用する.問題外の話をすると、異なる特徴の重要度(重み)を保存し、収束速度(例えば楕円が丸くなり、勾配が下がるのが速い)を速めるメトリック内で比較させます.分布状況をある程度変更し,これに対応する保存分布の標準化を行った.
    正規化コード:
    # dataSet is a list / to [0,1]
    def normList2Data(dataSet):
        dataSet = np.array(dataSet)
        minColVals = dataSet.min(0)
        maxColVals = dataSet.max(0)
        ranges = maxColVals - minColVals
        normDataSet = np.zeros(np.shape(dataSet))
        m = dataSet.shape[0]
        normDataSet = dataSet - np.tile(minColVals, (m, 1))
        normDataSet = normDataSet / np.tile(ranges, (m, 1))
        normDataSet = np.nan_to_num(normDataSet)
        return normDataSet
    
    
    def normalize(d):
        # d is a (n x dimension) np array
        d -= np.min(d, axis=0)
        d /= np.ptp(d, axis=0)
        d = np.nan_to_num(d)
        return d
    
    
    normList2Data()は手書きのコードであり、np.tile()は拡張行列が特定のshapeである関数である.normalize()では書き方が簡単で、np.ptp()は求めたrangeに直接戻ります.
    試験データを可逆的に使用するための正規化方法tf.math.l2_normalize output=x/sqrt(max(sum(x**2),epsilon))
    勾配降下を実現
    手動勾配降下
    線形回帰の勾配降下
    import os
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
    
    import tensorflow as tf
    import numpy as np
    from sklearn.datasets import fetch_california_housing
    from normalize import *
    from sklearn import preprocessing
    #      
    housing=fetch_california_housing()
    m,n=housing.data.shape
    # np.c_() column   ,     2      
    housing_data_plus_bias=np.c_[np.ones((m,1)),housing.data]
    
    print('housing_data_orig: {}'.format(housing_data_plus_bias[:5]))
    '''not invertible so that not use
    min_max_scaler = preprocessing.MinMaxScaler()
    x_scaled = min_max_scaler.fit_transform(housing_data_plus_bias)
    '''
    
    # housing_data_plus_bias=normalize(housing_data_plus_bias)
    # tf.nn.l2_normalize    ,output = x / sqrt(max(sum(x**2), epsilon))
    housing_data_plus_bias=tf.nn.l2_normalize(housing_data_plus_bias, dim = 0)
    # X=tf.constant(housing_data_plus_bias,dtype=tf.float32,name='X')
    
    # change attributes
    X=tf.cast(housing_data_plus_bias,dtype=tf.float32,name='X')
    y=tf.constant(housing.target.reshape(-1,1),dtype=tf.float32,name='y')
    
    XT=tf.transpose(X)
    
    theta=tf.matmul(tf.matmul(tf.matrix_inverse(tf.matmul(XT,X)),XT),y)
    
    with tf.Session() as sess:
        x_values=sess.run(X)
        theta_value=theta.eval()
        print(x_values[:10])
        print(theta_value)
    
    

    数値微分は依然として使いにくいことは明らかで、幸いtfはautodiffの自動微分がある.
    じどうびぶん
    import tensorflow as tf
    import numpy as np
    from sklearn.datasets import fetch_california_housing
    
    n_epochs = 1000
    learning_rate = 0.01
    
    housing = fetch_california_housing()
    m, n = housing.data.shape
    housing_data_plus_bias = np.c_[np.ones((m, 1)), housing.data]
    
    housing_data_plus_bias=tf.nn.l2_normalize(housing_data_plus_bias)
    # X=tf.constant(housing_data_plus_bias,dtype=tf.float32,name='X')
    
    X=tf.cast(housing_data_plus_bias,dtype=tf.float32,name='X')
    y=tf.constant(housing.target.reshape(-1,1),dtype=tf.float32,name='y')
    theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0), name='theta')
    y_pred = tf.matmul(X, theta, name='predictions')
    error = y_pred - y
    mse = tf.reduce_mean(tf.square(error), name='mse')
    # not autodiff: gradients = 2 / m * tf.matmul(tf.transpose(X), error)
    # d(ys)/d(xs)  
    # theta is like x-axis in 2D & use to calc partial derivative 
    # or say: gradients
    gradients=tf.gradients(mse,[theta])[0]
    training_op = tf.assign(theta, theta - learning_rate * gradients)
    
    
    init = tf.global_variables_initializer()
    
    with tf.Session() as sess:
        sess.run(init)
    
        for epoch in range(n_epochs):
            if epoch % 100 == 0:
                print("Epoch", epoch, " MSE = ", mse.eval())
            sess.run(training_op)
        best_theta = theta.eval()
    
    gradients=tf.gradients(mse,[theta])[0]
    tf.gradients(
        ys,
        xs,
        grad_ys=None,
        name='gradients',
        colocate_gradients_with_ops=False,
        gate_gradients=False,
        aggregation_method=None,
        stop_gradients=None
    )
    

    したがって、ys and xs are each a Tensor or a list of tensorsはリストを返します.
    さらにオプションの他のオプティマイザ:gradients=...training_op=...を次の2行に変更します.
    optimizer=tf.train.GradientDescentOpitimizer(learning_rate=learning_rate)
    training_op=optimizer.minimize(mse)
    

    小ロット勾配降下
    一般的な方法は、 を作成することであり、プレースホルダノードには計算のステップがなく、必要な値のみを出力する.プレースホルダノードを作成するには、次の手順に従います.
    A=tf.placeholder(tf.float32,shape=(None,3))
    B=A+5
    with tf.Session() as sess:
        B_val_1=B.eval(feed_dict={A:[[1,2,3]]})
        B_val_2=B.eval(feed_dict={A:[[2,3,4]]}
    
    print(B_val_1)
    print(B_val_2)
    

    モデルの保存
    ノードの実行後
    saver=tf.train.Saver()
    saver.restore(sess,'./my_model_final.ckpt')
    

    ノードの読み込み:
    saver.restore(sess,'./my_model_final.ckpt')