書き込み練習線形回帰NNの設定

29542 ワード

  • Collabご使用の際はご注意ください!実行時-実行時タイプを変更からGPUアクセラレータに変更しないと、モデルを作成してフィットしても損失は減少しません.(colabの場合はGPUを使用する必要があります)
  • import numpy as np 
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Input,Dense # Desne는 fully connected layer임 
    from tensorflow.keras import initializers
  • このようなplotであれば、train、testにほとんど差がないので、フィットしていないことが確認できます
  • weight値の初期化エラーは、完全に訓練できなくなります.epochを行っても値は減少しません.下図のように.
  • モデルの重みが毎回非常にランダムに初期値を設定すると、上記のような状況が発生します.
  • weightは無効な値に初期化され、localoptimaに陥り、トレーニングができません.
  • したがって、パラメータの初期化値を固定するためには、kernel initializerパラメータ値を各層に渡す必要がある.
  • モデル精度を測定する場合は、モデルの重み値を固定して初期化します。

    model = Sequential([Input(2,name='input_layer'),
    Dense(16,activation ='sigmoid',name='hidden_layer1',kernel_initializer=initializers.RandomNormal(mean=0.0,stddev=0.05,seed=42)),
    # Dense(10,activation ='sigmoid',name='hidden_layer2'), # 두전째 hidden layer. 이름이 같으면 안됨. 
    Dense(1,activation='relu',name='output_layer',kernel_initializer= initializers.RandomNormal(mean=0.0,stddev=0.05,seed=42))
      ])
    このようにすると、繰り返し実行も固定weight parameterに初期化されます.
  • kernel initializerパラメータが渡されない場合、回転するたびに重み値が変更されます.
  • 実験時にseed値を42に固定した.

  • kerasの順序でモデルを作成する


    y = 3x1 + 5x2+10
  • inputおよびoutputは、1つの層のモデルのみを含む.
  • Functionalのパターンもあり、ここでのシーケンスで十分です.(シーケンスにはいくつかの制限があります)
  • input layerからoutput layerまで順に記述
  • Sequencial layer各レイヤを作成し、これらのレイヤを接続します.
  • inputはx 1,x 2の2つの変数から値を得るため、input layerは[2,]
  • である.
  • Deseは完全接続を表します.
  • 16個のセルからなる隠蔽層を有するNNを生成する.
  • Output layerもDese layerであり、単一ユニットとして構成されている.
  • def gen_sequetial_model():
    
      
      model = Sequential([Input(2,name='input_layer'),
                          Dense(16,activation ='sigmoid',name='hidden_layer1',kernel_initializer=initializers.RandomNormal(mean=0.0,stddev=0.05,seed=42)),
                          # Dense(10,activation ='sigmoid',name='hidden_layer2'), # 두전째 hidden layer. 이름이 같으면 안됨. 
                          Dense(1,activation='relu',name='output_layer',kernel_initializer= initializers.RandomNormal(mean=0.0,stddev=0.05,seed=42))
      ])
    
      # model의 summary가 나온다 필요한parameter의 개수도 나온다. 
      # input - hidden 사이 parameter가 48개인것은,bias도 생각해서 (2+1)*16 =48인거
      # 마찬가지로 16+1 =17개 param
      model.summary()
    
      # Random 초기화한 weight값을 볼 수 있다.  
      # Dense에서 kernel_initialize 부분 코드가 없다면 돌릴 때 마다 ,weight값이 바뀐다
      print(model.layers[0].get_weights()) # first hidden layer의 weight,와 bias도 보여준다. Normal distribution에 의한 초기화  
      print(model.layers[1].get_weights()) 
    
      #predifned되어 있는 optimizer, loss func을 넣어주면됨
      model.compile(optimizer='sgd',loss='mse') 
      # 현재 linear regression이기에 loss func으로 MeaseSquaredError를 넣어준 것이고 
      # Multiclass classification같은 경우 CrossEntropy를 넣어줘야한다. 
      # optimizer에는 Adam도 있지. 
      
      return model
  • summary()表示
  • Edgeはa=wx+bであり、前層にn+1ノードがあるようにしている.その1はバイアスノードだと思いますbiasノードには値1が存在し、edgeのweightパラメータは1である.
  • 従って(2+1)16=48 param,(16+1)1=17 param

  • TrainとTestのテストデータセットの作成

  • 十分勉強するには(総パラメータ個数(65)*5)程度が必要です.
  • #  y = 3*x1 + 5*x2+10 을 만족하는 [x1,x2]데이터셋과 [y] 데이터셋을 생성하는 함수 (for training, testing)
    def gen_linear_regression_dataset(numofsamples = 500,w1=3,w2=5,b=10):
      
      np.random.seed(0)
      X = np.random.rand(numofsamples,2) # 0~1사이 값을 2차원으로 return
      print(X)
      print(X.shape)
    
      #y값을 만든다는
      coef = np.array([w1,w2]) #coefficient를 저장하는 1D. 
      bias = b
      
      # print(coef)
      # print(coef.shape) # 1*2 차원. 
      #for loop을 돌지 않기 위해, vectorized computation을 이런식으로 했다. 
      y = np.matmul(X,coef.transpose())+bias # bias는 broadcasting된다. 
      # X =(numofsamples,2) ,  coef.transpose() = )[2,1]
      # print(y)
      # print(y.shape)
    
      return X,y

    トレーニングコード

    model = gen_sequetial_model()
    x,y = gen_linear_regression_dataset(numofsamples=1000)
    
    # fit함수 사용해야함. train위해
    # epoch : 전체 data를 몇 번 스캐닝
    # verbose : 트레이닝 과정 각단계에서 loss값 
    # validation: 주어진 데이터를 자체적으로 train,dev set으로 split가능. 0.3이면  1000개중 300개를 dev set으로 사용하겠다. 
    
    history = model.fit(x,y,epochs=30,verbose=2,validation_split=0.3)
    

    バッチ

    def plot_loss_curve(history):
      import matplotlib.pyplot as plt
      
      plt.figure(figsize=(15,10))
    
      #training에 대한 loss와, validataion에 대한 loss가 각 epoch마다 저장이 되어있다. 
      plt.plot(history.history['loss'][1:]) 
      plt.plot(history.history['val_loss'][1:])
      plt.title('model loss')
      plt.ylabel('loss')
      plt.xlabel('epoch')
      plt.legend(['train','test'],loc='upper right')
      plt.show()
    
    plot_loss_curve(history)
    print(history.history)
    {'loss': [44.80178451538086, 1.9793720245361328, 1.7749576568603516, 
    1.6512281894683838, 1.5221993923187256, 1.4198955297470093, 1.3264726400375366,
     1.2410249710083008, 1.155310034751892, 1.0843353271484375, 1.0126545429229736, 
    0.9502711892127991, 0.889600932598114, 0.8315363526344299, 0.7800405621528625, 
    
    0.7311394214630127, 0.684747040271759, 0.6413758397102356, 0.6009031534194946, 
    0.5623612999916077, 0.5269203186035156, 0.4935012757778168, 0.4630745053291321, 
    0.4316529333591461, 0.40391528606414795, 0.37715470790863037, 0.35270997881889343, 
    0.331133097410202, 0.3080098330974579, 0.2879704535007477], 
    'val_loss': [2.444873332977295, 1.916710376739502, 1.7642972469329834, 
    1.6382949352264404, 1.5202995538711548, 1.4167743921279907, 1.3222960233688354, 1.2350214719772339, 1.1540216207504272, 1.0794423818588257, 1.0104804039001465, 0.9461767673492432, 0.8891554474830627, 0.8323615789413452, 0.7790414094924927, 0.7296032309532166, 0.6829895377159119, 0.6479376554489136, 0.6006353497505188, 0.5639929175376892, 0.5253522992134094, 0.4926072061061859, 0.4625047445297241, 0.43107956647872925, 0.406180202960968, 0.3767090141773224, 0.3515595495700836, 0.32803013920783997, 0.3084110915660858, 0.2858702838420868]}
    마지막 epoch에서의 loss값을 출력
    print("train loss = ",history.history['loss'][-1])
    print("test loss = ",history.history['val_loss'][-1])
  • sampleの数
  • また、このデータサンプルの個数はニューラルネットワークの複雑さに関係する(例えば、完全に接続されたネットワークでは、レイヤの個数とレイヤ単位当たりの個数が大きいほど、パラメータの個数が大きくなる)
  • epochの数もloss
  • に影響する
  • epochは大幅に増加し、収束しているように見える場合は、epochを追加する必要はありません.
  • Test code


    epochは1000なので
    def predict_new_sample(model,x,w1=3,w2=5,b=10):
      x=x.reshape(1,2)
      y_pred = model.predict(x)[0][0]
    
      y_actual = w1*x[0][0]+w2*x[0][1]+b
      print("y actualvalue = ",y_actual)
      print("y predicted value = ",y_pred)
    
    predict_new_sample(model,np.array([0.1,0.2]))
    y actualvalue = 11.3
    y predicted value = 11.257002
  • NNは任意のMLProblem、回帰、関数を解くことができる.
  • NNにより、リニア再生も可能です.
  • linear regressionは3つのパラメータしかない問題で、これは65のパラメータがあります.
  • 数学的線形関数は提供されていません...