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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

928閲覧

if文:return Trueやreturn Falseの使い方について

chronobcelp

総合スコア9

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/01/07 11:35

編集2022/01/07 13:34

前提・実現したいこと

TensorFlow2 TensorFlow&Keras対応 プログラミング実装ハンドブック P.338-340で質問があります。

以下のコードで書かれているif文のreturn Trueやreturn Falseの使い方がわかりません。
ループを抜ける操作に関わると思いますが、このような使い方は見たことがなくて、自分で色々調べてもわかりませんでした。
return True = break, return False = continueといった感じでしょうか?

よかったら教えていただけないでしょうか?
どこかに参考になるページがあったら、添付していただけないでしょうか?
よろしくお願いします。

該当のソースコード

Python

1''' 27.学習の進捗を監視し早期終了判定を行うクラス 3''' 4class EarlyStopping: 5 def __init__(self, patience=10, verbose=0): 6 ''' 7 Parameters: 8 patience(int): 監視するエポック数(デフォルトは10) 9 verbose(int): 早期終了の出力フラグ 10 出力(1),出力しない(0) 11 ''' 12 # インスタンス変数の初期化 13 # 監視中のエポック数のカウンターを初期化 14 self.epoch = 0 15 # 比較対象の損失を無限大'inf'で初期化 16 self.pre_loss = float('inf') 17 # 監視対象のエポック数をパラメーターで初期化 18 self.patience = patience 19 # 早期終了メッセージの出力フラグをパラメーターで初期化 20 self.verbose = verbose 21 22 def __call__(self, current_loss): 23 ''' 24 Parameters: 25 current_loss(float): 1エポック終了後の検証データの損失 26 Return: 27 True:監視回数の上限までに前エポックの損失を超えた場合 28 False:監視回数の上限までに前エポックの損失を超えない場合 29 ''' 30 # 前エポックの損失より大きくなった場合 31 if self.pre_loss < current_loss: 32 # カウンターを1増やす 33 self.epoch += 1 34 # 監視回数の上限に達した場合 35 if self.epoch > self.patience: 36 # 早期終了のフラグが1の場合 37 if self.verbose: 38 # メッセージを出力 39 print('early stopping') 40 # 学習を終了するTrueを返す 41 return True 42 # 前エポックの損失以下の場合 43 else: 44 # カウンターを0に戻す 45 self.epoch = 0 46 # 損失の値を更新する 47 self.pre_loss = current_loss 48 49 # 監視回数の上限までに前エポックの損失を超えなければ 50 # Falseを返して学習を続行する 51 # 前エポックの損失を上回るが監視回数の範囲内であれば 52 # Falseを返す必要があるので、return文の位置はここであることに注意 53 return False

コード追加分

該当のソースコード

python

1%%time 2''' 38.モデルを生成して学習する 4''' 5from sklearn.utils import shuffle 6 7# エポック数 8epochs = 100 9# ミニバッチのサイズ 10batch_size = 64 11# 訓練のステップ数 12train_steps = len(x_train)*0.8 / batch_size 13# 検証のステップ数 14val_steps = len(x_train)*0.2 / batch_size 15# 訓練と検証における損失と精度の推移を記録するdictオブジェクト 16history = {'loss':[], 'accuracy':[], 17 'val_loss':[], 'val_accuracy': []} 18 19# 早期終了の判定を行うオブジェクトを生成 20ers = EarlyStopping(patience=20, # 監視対象回数 21 verbose=1) # 早期終了時にメッセージを出力 22 23# 出力層10ニューロンのモデルを生成 24model = CNN(10) 25 26# ImageDataGeneratorを生成 27datagen = keras.preprocessing.image.ImageDataGenerator( 28 rescale=1.0/255.0, # ピクセル値を255で割って正規化する 29 validation_split=0.2, # 20パーセントのデータを検証用にする 30 rotation_range=15, # 15度の範囲でランダムに回転させる 31 width_shift_range=0.1, # 横サイズの0.1の割合でランダムに水平移動 32 height_shift_range=0.1, # 縦サイズの0.1の割合でランダムに垂直移動 33 horizontal_flip=True, # 水平方向にランダムに反転、左右の入れ替え 34 zoom_range=0.2, # ランダムに拡大 35) 36 37# 訓練データ用のジェネレーターを生成 38training_generator = datagen.flow(x_train, t_train, 39 batch_size=batch_size, 40 subset='training') # 訓練用のデータを生成 41# 検証データ用のジェネレーターを生成 42validation_generator = datagen.flow(x_train, t_train, 43 batch_size=batch_size, 44 subset='validation') # 検証用のデータを生成 45 46# 学習を行う 47for epoch in range(epochs): 48 # 訓練時のステップカウンター 49 step_counter = 0 50 # 1ステップ毎にミニバッチで学習する 51 for x_batch, t_batch in training_generator: 52 # ミニバッチでバイアス、重みを更新 53 train_step(x_batch, t_batch) 54 step_counter += 1 55 # すべてのステップが終了したらbreak 56 if step_counter >= train_steps: 57 break 58 59 # 検証時のステップカウンター 60 v_step_counter = 0 61 # 検証データによるモデルの評価 62 for x_val_batch, t_val_batch in validation_generator: 63 # 検証データのミニバッチで損失と精度を測定 64 val_step(x_val_batch, t_val_batch) 65 v_step_counter += 1 66 # すべてのステップが終了したらbreak 67 if v_step_counter >= val_steps: 68 break 69 70 # 訓練と検証における損失と精度の推移をhistoryに記録 71 history['loss'].append(train_loss.result()) 72 history['accuracy'].append(train_acc.result()) 73 history['val_loss'].append(val_loss.result()) 74 history['val_accuracy'].append(val_acc.result()) 75 76 # 1エポックごとに結果を出力 77 print('epoch({}) train_loss: {:.4} train_acc: {:.4}' 78 'val_loss: {:.4} val_acc: {:.4}'.format( 79 epoch+1, 80 train_loss.result(), # 訓練データの損失を出力 81 train_acc.result(), # 訓練データの精度を出力 82 val_loss.result(), # 検証データの損失を出力 83 val_acc.result() # 検証データの精度を出力 84 )) 85 86 # 検証データの損失をEarlyStoppingオブジェクトに渡して早期終了を判定 87 if ers(val_loss.result()): 88 # 監視対象のエポックで損失が改善されなければ学習を終了 89 break

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

EarlyStoppingは学習が進まなくなったところで止めるものです。
なので、EarlyStoppingクラス__call__関数は学習が進んでいるか進んでいるかを判定する関数であり、return Truereturn Falseはそれぞれ結果として返しています。

おそらくこのクラスを呼び出して使っている部分で__call__関数Trueを返した時点で学習が進んでいないと判断して、学習が止まるようになっているのだと思います。

python

1if EarlyStopping.__call__: 2 [学習を終了する処理]

投稿2022/01/07 13:17

kyokio

総合スコア560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chronobcelp

2022/01/07 13:36

その通りでした。コードを追加しました。 if ers(val_loss.result()): break ここで、ers(val_loss.result())=Trueとなるまで、繰り返していたんですね。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問