7/2

様々なCNNモデル(の組み合わせ4パターンは以下に記載)を試したが学習時間・精度ともに元々学習に使っていた"EfficientNetV2S", "DenseNet121", "MobileNetV3Large" の組み合わせが1番であったためこれから当面の間はMMLI.py と CNN+binning3.pyで錆画像の判別を行っていくこととする。

6/23

特徴 / スクリプト名CNN+binning.pyCNN+binning2.pyCNN+binning3.pyCNN+binning4.py
モデルの種類オリジナルCNN3種強化CNN(層数増加)EfficientNetV2S / DenseNet121 / MobileNetV3同左
アンサンブル学習
出力形式回帰+binning回帰+binning回帰+binning回帰+Sigmoid正規化+binning
Soft Labeling(評点ぼかし)
損失関数MSE+重みペナルティ強化ペナルティ損失関数同左同左
特徴量の利用×××○(画像+数値特徴:面積、粒径、Sobel量)
特徴量融合方法CNN出力ベクトル+数値特徴 → Dense結合
出力スケーリング×××○(シグモイド関数+0〜5.0スケーリング)
カスタムbinning関数
UMAP可視化
判別補正(3⇔4の補正など)×××○(特徴量条件付き補正が可能な構造)
使用層の深さ・複雑さ普通やや深め深層+転移学習モデル同左

手書き数字の画像をCNNで機械学習するのに必要な画像とPythonファイル

5/21

ただVer5.0は様々な学習要素を詰め込んでしまったのが原因なのか判別精度がかえって落ちてしまったため、今後手書き数字の画像判別を行なう際にはVer4.0のスクリプトで実行することを勧めておく。

5/14

0_0.png ー画像加工→ modified_0_0.png

5_0.png ー画像加工→ modified_5_0.png

7_2.png ー画像加工→ modified_7_2.png

1_0.png 4_0.png 9_0.png noised_1_0.png noised_4_0.png noised_9_0.png

5/7

錆の写真からSVMで機械学習するまでの流れ

この一連の流れは同じファイル内に保存するのが望ましい

20250428-1.png

http://www.str.ce.akita-u.ac.jp/~gotouhan/j2024/morii/20250424-2.png → http://www.str.ce.akita-u.ac.jp/~gotouhan/j2024/morii/20250424-3.png

GIMPでの画像の切り取り方(200×200ピクセルの場合)

環境整備

Anaconda

インストールが終了すると

Do you wish to update your shell profile to automatically initialize conda?
This will activate conda on startup and change the command prompt when activated.
If you'd prefer that conda's base environment not be activated on startup,
   run the following command when conda is activated:

conda config --set auto_activate_base false

You can undo this by running `conda init --reverse $SHELL`? [yes|no]

みたいに出る。

「yes」を選ぶと、condaが自動で初期化され、端末を開いた時点でbase環境がアクティブになります。プロンプト表示 内容も変わります。
「no」を選ぶと、通常はcondaコマンドを手動で有効化(例:conda activate base)する必要があります。

ということなので、パソコン起動時から常駐されたくないから、noを選ぶ。

.bashrcを.bashrc.bakにバックアップを取ってから、末尾に

export PATH=/home/kouzou/anaconda3/bin:$PATH

みたいに書き込む(ユーザー名がkouzouの場合)。 で、bashrcを有効にするために、

$. .bashrc

と打ち込んでから(あるいはターミナルを起動し直して)、condaと打ち込んで

usage: conda [-h] [-v] [--no-plugins] [-V] COMMAND ...

みたいに出ればよい。

anaconda-navigatorがエラーで起動しない

ターミナルでanaconda-navigatorと打ち込んで、

Could not initialize GLX
中止 (コアダンプ)

となる場合。

jupyterを使うことが目的の場合は、

jupyter lab
jupyter notebook

などで、ブラウザーで使うとうい方法がある。

vscode

$ sudo snap install --classic code

codeと打ち込んで起動できればよい。 view→Command Palette...検索欄>にdisplayと打ち込んで、Configure Display Languageを選択→日本語を選択

tensorflow

$ pip install --upgrade pip
$ pip install tensorflow 

pipはPython用パッケージマネージャー。 インストール終了したら、pythonと打ち込んで、Python対話モードを起動する。 プロンプトが>>>になったら、以下のように入力してみる。 エラーが出ずにバージョンが表示されればよい。

>>> import tensorflow as tf
>>> print(tf.__version__)

ランダム性

以下のプログラムで、まずset1でEfficientNetV2S、DenseNet121、MobileNetV3Largeのモデルをそれぞれ計算し、その後にアンサンブル学習を行っています。次に、set2でInceptionResNet、XceptionV2、DenseNet121のモデルをそれぞれ計算し、その後にアンサンブル学習を行っています。このとき、set1でまず計算したDenseNet121の結果(mae_scoreやacc_score)が、set2で計算したDenseNet121の結果(mae_scoreやacc_score)と数パーセントずれるのはなぜですか。

非常に良い質問です。 DenseNet121 を両方のセット(set1・set2)で使っているのに、 MAE や Accuracy が数%ずれるのは ―― スクリプト上で理論的には「同じ条件」に見えても、 実際には完全な再現性が保証されていないためです。

以下に、なぜ差が生じるのかを技術的に解説します。 🧩 差が出る主な原因 ① モデル初期化のランダム性

base = DenseNet121(include_top=False, weights="imagenet", input_tensor=input_img)

   weights="imagenet" で初期化する場合、重みは固定されていますが、
   上に積んでいる全結合層 (Dense, Dropout, BatchNormalization) は毎回ランダム初期化されます。

➡️ set1 と set2 で 別インスタンスの DenseNet121 を作成しているため、 上位層の重み初期値が異なり、学習曲線がわずかに変化します。 ② Data Augmentation と Soft Labeling の乱数

コード内で次の処理があります👇

score += np.random.uniform(-0.2, 0.2) # Soft Labeling

また、Data Augmentation(ランダム回転・明度変換など)を適用している場合:

tf.image.random_brightness, random_contrast, random_hue ...

➡️ これらのランダム性は、Python・NumPy の seed 固定だけでは完全に抑止できません。 TensorFlow 内部のデータパイプラインが独自に乱数を生成するためです。 ③ 学習過程における GPU / 並列演算の非決定性

TensorFlow + cuDNN(GPU)の場合、 特定のレイヤー(特に BatchNormalization, Dropout)で 計算順序や浮動小数誤差の違いにより、結果が微妙に変わります。

   例:同じ初期値でも、計算を別のGPUスレッドで行うと小数第6位以降が変化 →
   それが累積して MAE/ACC が ±1〜3% 変化することも。

④ 2回目の DenseNet121 の学習が完全に独立

set1 と set2 は以下のように完全に独立して実行されています:

result1 = run_experiment(..., model_set="set1") result2 = run_experiment(..., model_set="set2")

そのため、set2 の DenseNet121 は set1 の学習結果を引き継いでいません。 たとえ構造が同じでも、別々に初期化・最適化・EarlyStopping されているため、 誤差1〜3%のズレはごく自然な範囲です。 🧠 つまり — DenseNet121 の差は「同じモデル構造でも別の学習経路を通った」ため

   set1 と set2 の DenseNet121 は パラメータ初期値が異なる別個体。
   Soft Labeling と Data Augmentation のランダム性も加わり、
   → MAE, Accuracy, F1 が数%ずれる。

✅ 差を最小化したい場合の対策 対策 内容 ① 乱数の完全固定 random.seed, np.random.seed, tf.random.set_seed に加え、 os.environ["TF_DETERMINISTIC_OPS"]="1" を設定(あなたのスクリプトはOK) ② Data Augmentation を停止 ランダム操作をすべて無効化して「同一データ」で学習 ③ Soft Labeling を固定化 np.random.uniform(-0.2, 0.2) をやめるか、固定値に置き換える ④ GPUを無効化 CPU演算は遅いが、決定論的に動作するため再現性が高い ⑤ 同一モデルを再利用 set2でDenseNet121を再インスタンス化せず、set1の学習済みモデルを再評価する 📘 まとめ(Wiki掲載用に適した説明)

   DenseNet121 の結果が set1 と set2 で数%異なる理由
   同一モデル構造を使用していても、学習の初期化やデータのランダム性により結果が完全には一致しません。
   具体的には、①重みの初期化、②Soft LabelingやData Augmentationの乱数、③GPUの並列演算における非決定性などが影響します。
   そのため、全く同じ条件で再現性を保証するには、乱数固定に加え、データ拡張を停止し、GPUではなくCPUモードで決定論的演算を行う必要があります。

もし希望があれば、 「このスクリプトで完全に再現性を確保する設定(CPU強制・Augmentation無効・ラベル固定)」 を実装した改良版も書けます。 作成しましょうか? あなた: アンサンブル学習ではなく、DenseNet121のモデルを単独で計算させた場合でも、計算するたびに、こうしたランダム性による影響で毎回、結果が数パーセント変わりますか。あるいは、アンサンブル学習に特有の現象ですか ChatGPT:

非常に鋭い質問です。 結論から言うと――

   はい、DenseNet121を単独で計算した場合でも、毎回結果は数%程度変動します。
   これはアンサンブル特有の現象ではなく、ニューラルネットワークの学習全般に内在する「非決定性(nondeterminism)」 に起因するものです。

🧩 単独モデル(例:DenseNet121単体)でも結果が変わる主な理由 ① 重み初期値のランダム性

Keras/TensorFlow は各層(Dense, BatchNormなど)の初期重みをランダムで設定します。

x = layers.Dense(512, activation="relu")(x)

たとえ同じデータ・同じエポック数でも、 初期重みがわずかに違えば、最終的に収束する重みが異なるため、 MAEやAccuracyに1〜3%(場合によっては5%)ほど差が出ます。 ② Data Augmentationのランダム性

tf.image.random_brightness, random_flip, random_hue などを使うと、 各エポックで入力データがランダムに変化します。

このため:

   同じ画像が「異なる明るさ・彩度」で学習される
   結果として学習経路が毎回少しずつ異なる

➡️ 同じDenseNet121でも、毎回微妙に異なる学習パターンになります。 ③ GPU演算の非決定性

TensorFlow + cuDNN (GPU) では以下のような「非決定的な演算」が含まれます。

   並列演算の順序が変わる(浮動小数誤差が累積)
   BatchNormalization や Dropout の内部処理にランダム性がある

これにより、全く同じコードを2回実行しても結果が異なることがあります。 特に DenseNetBatchNorm を大量に含むため、影響が顕著です。 ④ EarlyStopping や Validation Split の影響

EarlyStopping もまたランダム分割 (train_test_split) に依存しています。 例えば random_state=42 を固定しても、Augmentation や Dropout のタイミングで validation loss の最小点がずれることがあります。 🧠 対して「アンサンブル学習」ではどうなるか

アンサンブル(複数モデルの平均)はむしろ個々のランダム性を平均化して安定化します。 したがって:

   単独モデルよりも結果は安定しやすい
   しかし、「同じアンサンブルを2回作る」ときには、やはり個々のモデルの初期値が異なるため、再現性は完全ではない

✅ まとめ(Wiki掲載用にも適した説明)

   DenseNet121 単独でも再現性は完全ではない
   ニューラルネットワークの学習には、初期重み、Data Augmentation、GPU演算、Dropoutなど多くのランダム要素が含まれます。そのため、同一条件でDenseNet121を単独で学習させても、結果(MAEやAccuracyなど)が数パーセント変動することがあります。
   一方、アンサンブル学習はこれらのランダム性を平均化して安定させる効果がありますが、アンサンブル全体を再構築する場合も完全な再現性は保証されません。

もし「DenseNet121の結果を完全に再現」したい場合は、 次のような設定を行うとよいです👇

import os, random, numpy as np, tensorflow as tf

os.environ["PYTHONHASHSEED"] = "42" os.environ["TF_DETERMINISTIC_OPS"] = "1" os.environ["TF_CUDNN_DETERMINISTIC"] = "1"

random.seed(42) np.random.seed(42) tf.random.set_seed(42)

# GPUではなくCPUで実行 tf.config.set_visible_devices([], 'GPU')

これでランダム性を最大限抑えられます。 (ただしCPUのみ実行になるため学習時間は大幅に増えます。)

ご希望があれば、「DenseNet121を完全再現性モードで1回ずつ学習・評価する最小スクリプト」を示しますが、作成してみましょうか?


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS