質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.72%

kerasで損失関数をいじる.(損失関数を自作?)

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 1,150

FALLOT

score 14

今までは
model.compile(loss='mean_absolute_percentage_error', optimizer=opt)
のようにいきなり損失化数を代入しただけでした.
kerasでデフォルトで
y_true: 正解ラベル.TensorFlow/Theano テンソル
y_pred: 予測値.y_trueと同じshapeのTensorFlow/Theano テンソル
となっていますが,
loss_fun = mean_absolute_error(y_true/width, y_pred/width)
という感じに書き直したいのですがうまくできません.
どのようにすればよいですか.

#最大応力の値の予測
from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, LeakyReLU
#from keras.layers.advanced_activations import LeakyReLU
from keras.utils.np_utils import to_categorical
from keras.optimizers import Adagrad
from keras.optimizers import Adam
from keras.models import load_model
from keras.callbacks import EarlyStopping, ModelCheckpoint, CSVLogger
from sklearn.model_selection import train_test_split
from sklearn import datasets
import numpy as np
from PIL import Image
import os
import time
import csv
import cv2
import math


start_time = time.time()
print("開始時刻: " + str(start_time))
#それぞれの画像の枚数を入力
A = 50
B = 50
sum =A+B
# 学習用のデータを作る.
image_list = []
location_list = []
#ハイパーパラメータ
#画像サイズ
x = 150
y = 75
Z = x*y #入力層のノード数
#エポック数
E = 100
#バッチサイズ
BATCH_SIZE = 32
#学習率
LR = 0.00001
#訓練データの数 train=sum
train=sum

#画像の読み込み:読み込み→リサイズ→1列に変換→正規化
print("画像の読み込み 開始")
count=1
for i in range(0,A):
    im = cv2.imread("data/image/a/"+str(i)+"a.png".format(i),1) #画像の読み込み
    print(str(i)+"a.png")
    image = np.array(Image.open("data/image/a/"+str(i)+"a.png").resize((x, y))) #画像をnum配列にしてリサイズ
    print(image.shape)
    image =np.reshape(image,Z) #2次元行列を1次元行列に変換
    print(image.shape)
    image_list.append(image / 255.) #appendは追加:1枚ずつ足しこんでいく
    print(str(count)+"/"+str(train))
    count +=1
    print('\n')

for i in range(0,B):
    im = cv2.imread("data/image/b/"+str(i)+"b.png".format(i),1) #画像の読み込み
    print(str(i)+"b.png")
    image = np.array(Image.open("data/image/b/"+str(i)+"b.png").resize((x, y))) #画像をnum配列にしてリサイズ
    print(image.shape)
    image =np.reshape(image,Z) #2次元行列を1次元行列に変換
    print(image.shape)
    image_list.append(image / 255.) #appendは追加:1枚ずつ足しこんでいく
    print(str(count)+"/"+str(train))
    count +=1
    print('\n')

print("画像の読み込み 終了")

# kerasに渡すためにnumpy配列に変換。
image_list = np.array(image_list)

#最大応力の位置_読み込み_表示
location = np.loadtxt("data/value/max_stress_value_a.csv",delimiter=",",skiprows=0)
location_list.extend(location)
location = np.loadtxt("data/value/max_stress_value_b.csv",delimiter=",",skiprows=0)
location_list.extend(location)
location_list = np.array(location_list)
print("\n最大応力の値の行列の形")
print(location_list.shape)
np.savetxt("data/value/max_stress_value_true.csv",location_list,delimiter=",")
#最大応力の位置_読み込み_終了

# モデルを生成してニューラルネットを構築
model = Sequential()

model.add(Dense(5000, input_dim=Z,kernel_initializer='random_uniform',bias_initializer='zeros')) 
model.add(LeakyReLU())
model.add(Dropout(0.2))

model.add(Dense(100,kernel_initializer='random_uniform',bias_initializer='zeros'))
model.add(LeakyReLU())
model.add(Dropout(0.075))

model.add(Dense(10,kernel_initializer='random_uniform',bias_initializer='zeros'))
model.add(LeakyReLU())
model.add(Dropout(0.0))

model.add(Dense(5,kernel_initializer='random_uniform',bias_initializer='zeros'))
model.add(LeakyReLU())
model.add(Dropout(0.0))

model.add(Dense(1))
model.add(Activation("linear"))

# オプティマイザ(最適化)にAdamを使用
opt = Adam(lr=LR)

width =3.45
def loss_function(y_true,y_pred):
    return abs(y_pred-y_true)/width*100

#loss_fun = mean_absolute_error(y_true/width, y_pred/width)

# モデルをコンパイル
#最大応力位置の予測 誤差関数:相対誤差
#model.compile(loss="mean_absolute_percentage_error", optimizer=opt)
model.compile(loss='mean_absolute_error(y_true/width, y_pred/width)', optimizer=opt)

#CSVに各エポックの学習結果の保存
csv_logger = CSVLogger('result/training_process.csv')

# 学習を実行。20%はテストに使用
#最大応力位置の予測 モデルフィット
history = model.fit(image_list, location_list, nb_epoch=E,verbose=1,callbacks=[csv_logger], batch_size=BATCH_SIZE, validation_split=0.2) 

#最大応力位置の予測 誤差の評価
loss = model.evaluate(image_list, location_list)

#最終の学習結果を書き込む
fp = open("result/RESULT.txt","w")
fp.write("\nloss:{}".format(loss))
fp.close()

#最終の誤差の表示
print("\nloss:{}\n".format(loss))


image_list = np.array(image_list)
location_list = np.array(location_list) 


def get_batch(x, y, batch_size, shuffle=False):
    '''ミニバッチを生成するジェネレーター関数
    '''
    num_samples = len(x)
    if shuffle:
        indices = np.random.permutation(num_samples)
    else:
        indices = np.arange(num_samples)

    num_steps = np.ceil(num_samples / batch_size).astype(int)
    # ステップ数 = ceil(サンプル数 / バッチサイズ)
    # 例 np.ceil(10 / 3) = np.ceil(3.33333333...) = 4

    for itr in range(num_steps):
        start = batch_size * itr
        excerpt = indices[start:start + batch_size]
        yield x[excerpt], y[excerpt]

# 保存用ディレクトリ
out_dirpath = 'prediction'
os.makedirs(out_dirpath, exist_ok=True)

# 学習する。
epochs = E
for i in range(epochs):  # エポック数分ループする。
    for x_batch, y_batch in get_batch(image_list, location_list, batch_size=BATCH_SIZE, shuffle=True):
        # 1バッチ分学習する
        model.train_on_batch(x_batch, y_batch)
    print('training... epoch {}'.format(i))

    # エポックごとにテストデータで推論する。
    y_pred = model.predict(image_list)
    result = np.c_[y_pred, location_list]

    # 推論結果を保存する。
    filepath = os.path.join(out_dirpath, 'prediction_{}.csv'.format(i))
    np.savetxt(filepath, result, fmt='%.6f', delimiter=',') 

end_time = time.time()
print("\n終了時刻: ",end_time)
print ("かかった時間: ", (end_time - start_time))
ttime = end_time - start_time
fa = open("result/TIME.txt","w")
fa.write("\nかかった時間:{} ".format(ttime))
fa.close()
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.72%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる