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

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

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

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

受付中

複数の画像データの標準化

ktktkt
ktktkt

総合スコア0

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

3回答

0グッド

0クリップ

431閲覧

投稿2022/10/12 09:12

編集2022/10/12 09:18

前提

ある論文の再現をしようとしていますが、画像の標準化のところで苦戦しています。
使用言語はpythonです。
目標としては以下の図のような標準化をしたいと考えています。
(a)が元画像、(b)が標準化後です。
イメージ説明

論文中のデータセットは以下のようになっています。
一つのインデックスには画像のサイズである60×160の計9600次元が特徴量として入力されています。
画像は2880枚あり各画像がインデックスを担っています。
応答値は画像と関係ないので省きます。
イメージ説明

標準化は以下の画像に示した式に従い行っているそうです。
なお、iは番号(画像の番号)、jは列番号(特徴量の番号)を示しており、μは平均、σは標準偏差を示しているそうです。
イメージ説明

実現したいこと

前提で提示したような標準化画像が得たい。
現在は前段階として画像枚数を5枚のデータセットで実現しようとしている。
ライブラリーインポート後に画像の読み込み、サイズの変更などをしている。
イメージ説明

その後データセットを作成した。イメージ説明

データセット作成後に各値を変数に代入した。
イメージ説明

代入後にいよいよ標準化したらエラーが出てきた。
標準化のコードは以下のとおりである。
イメージ説明

発生している問題・エラーメッセージ

SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy df_copy[index_count][colum_count]=(df[index_count][colum_count]-df_mean[colum_count])/df_std[colum_count] --------------------------------------------------------------------------- ValueError Traceback (most recent call last) File ~\anaconda3\lib\site-packages\pandas\core\indexes\range.py:385, in RangeIndex.get_loc(self, key, method, tolerance) 384 try: --> 385 return self._range.index(new_key) 386 except ValueError as err: ValueError: 5 is not in range The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) Input In [17], in <cell line: 1>() 1 for colum_count in range(colum_counts): 2 for index_count in range(index_counts): ----> 3 df_copy[index_count][colum_count]=(df[index_count][colum_count]-df_mean[colum_count])/df_std[colum_count] File ~\anaconda3\lib\site-packages\pandas\core\series.py:958, in Series.__getitem__(self, key) 955 return self._values[key] 957 elif key_is_scalar: --> 958 return self._get_value(key) 960 if is_hashable(key): 961 # Otherwise index.get_value will raise InvalidIndexError 962 try: 963 # For labels that don't resolve as scalars like tuples and frozensets File ~\anaconda3\lib\site-packages\pandas\core\series.py:1069, in Series._get_value(self, label, takeable) 1066 return self._values[label] 1068 # Similar to Index.get_value, but we do not fall back to positional -> 1069 loc = self.index.get_loc(label) 1070 return self.index._get_values_for_loc(self, loc, label) File ~\anaconda3\lib\site-packages\pandas\core\indexes\range.py:387, in RangeIndex.get_loc(self, key, method, tolerance) 385 return self._range.index(new_key) 386 except ValueError as err: --> 387 raise KeyError(key) from err 388 self._check_indexing_error(key) 389 raise KeyError(key) KeyError: 5

該当のソースコード

for colum_count in range(colum_counts): for index_count in range(index_counts): df_copy[index_count][colum_count]=(df[index_count][colum_count]-df_mean[colum_count])/df_std[colum_count]

試したこと

どこから間違っているのかもわかりません。
そもそも論文では60×160というサイズ表記で9600次元のところもRGBのデータがないのがよくわかっていません。
わかることがあれば些細なことでも教えていただけると助かります。

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

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

以下のような質問にはグッドを送りましょう

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

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

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答3

0

1.エラーの解決方法
df[i][j]ではiが列、jが行に対応してしまいます。
行と列が入れ替わってしまうので、エラーメッセージで「6行目はありませんよ」と出てしまっています。

解決方法は、df.iat[i,j]を使うことです。こちらはiが行、jが列に対応します(iatの使い方の参考リンク)
df_copy[index_count][colum_count]のところで、df_copy.iat[index_count,colum_count]のように使います。
df[index_count][colum_count]も同様に、df.iat[index_count,colum_count]と書き換えてください。

2.コード中のバグが起きそうな箇所
df_copy=df
とするのは危険です。
df_copyを変更したときにオリジナルのdfも変更されてしまうので、バグの原因になります(参考リンク)
df_copy = df.copy()
とするのが良いです。

3.RGBチャンネルの扱い
RGBチャンネルを足し合わせて1つにまとめるには、np.sum()が使えます。
flattenする前のarrayに対して、np.sum(array, axis=2)として使います。
平均ではなく合計のsumにした理由は、小数点型にしないためです。
また、後に標準化するので、結果は変わらないはずです。
ただし、本当にsumが適切かどうかは、元論文の手法の部分をよく確認してみてください。

投稿2022/10/12 11:26

T_F

総合スコア74

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

0

python

1import pandas as pd 2df = pd.DataFrame([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) 3print(df.values) 4''' 5[[ 0 1 2 3 4] 6 [ 5 6 7 8 9] 7 [10 11 12 13 14]] 8''' 9 10# 母標準偏差 11df_copy0 = (df - df.mean()) / df.std(ddof=0) 12print(df_copy0.values) 13''' 14[[-1.22474487 -1.22474487 -1.22474487 -1.22474487 -1.22474487] 15 [ 0. 0. 0. 0. 0. ] 16 [ 1.22474487 1.22474487 1.22474487 1.22474487 1.22474487]] 17''' 18 19# 標本標準偏差 20df_copy1 = (df - df.mean()) / df.std(ddof=1) 21print(df_copy1.values) 22''' 23[[-1. -1. -1. -1. -1.] 24 [ 0. 0. 0. 0. 0.] 25 [ 1. 1. 1. 1. 1.]] 26'''

 
参考
Pythonで正規化・標準化(リスト、NumPy配列、pandas.DataFrame)

投稿2022/10/12 10:40

jbpb0

総合スコア7521

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

0

一般化すると確かにそのような数式になりますが,Numpyには便利なブロードキャスト機能があるので活用しましょう.次のように書くと標準化できます.

Python

1data = list() 2for file in im_file_list: 3 img = np.array(Image.open(file)).flatten() 4 data.append(img) 5data = np.array(data) 6data = (data - data.mean(axis = 0)) / data.std(axis = 0) # feature-wise normalization 7# data = ((data.T - data.mean(axis = 1)) / data.std(axis = 1)).T # sample-wise normalization 8# data = (data - data.mean()) / data.std() # dataset-wise normalization

画像処理におけるfeature-wise normalizationはあまり見かけないので,精度の向上が見込めなかったら他のものも試してみると良いでしょう.

そもそも論文では60×160というサイズ表記で9600次元のところもRGBのデータがないのがよくわかっていません

もしかしたら論文では,RGB画像をグレースケール画像にしてから,上述の処理をしているのかもしれませんね.元画像も彩度が低く,白黒画像にしても問題ないような画像なので,そういった画像データに対してグレースケール変換はよく取られる手法の1つではあります.グレースケールで開く場合は,Image.open(file).convert('L')としましょう.

投稿2022/10/12 09:32

編集2022/10/12 13:03
PondVillege

総合スコア1066

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

jbpb0

2022/10/12 10:49

質問の数式を見ると、列番号「j」毎の平均値と標準偏差値を使って標準化をしてます 各列で(特徴量毎に)標準化する、という意味だと思います この回答のコードだと、各行で(画像毎に)標準化するので、上記とは異なる結果になると思います
PondVillege

2022/10/12 12:03 編集

先入観で見誤っておりました,確かにそうですね.コードも修正いたしました. 特徴量ごとに標準化するのは構造化データに対して行うには確かに正しいですが,果たして画像ごとの同じ位置のピクセルに対する標準化はどうなんでしょうね...KerasのImageDataGeneratorで例えると,私の間違っていた方と同様のsamplewiseな標準化と,全画像に対してのdatasetwise(リファレンスではfeturewise呼び)な標準化しかないので,違和感があります. 例示いただいている標準化後データも,画像単体で標準化しているように見えないこともないですが... まぁ,背景差分法が使えそうなぐらいの定点画像データセットであれば,有効かもしれませんね.
jbpb0

2022/10/12 12:12

> 例示いただいている標準化後データも,画像単体で標準化しているように見えないこともないですが... が、私の回答の計算結果例のことならば、画像毎に標準化したら下記のようになります # 母標準偏差 [[-1.41421356 -0.70710678 0. 0.70710678 1.41421356] [-1.41421356 -0.70710678 0. 0.70710678 1.41421356] [-1.41421356 -0.70710678 0. 0.70710678 1.41421356]] # 標本標準偏差 [[-1.26491106 -0.63245553 0. 0.63245553 1.26491106] [-1.26491106 -0.63245553 0. 0.63245553 1.26491106] [-1.26491106 -0.63245553 0. 0.63245553 1.26491106]]
PondVillege

2022/10/12 12:23

すみません,質問者の例示した画像のことでした. samplewiseの標準化が有効なシーンは画像のように数値が値域に満遍なく存在しているときでしょうか,jbpb0さんの例示したデータではあまり有効に見えませんね.画像で言えば単一画像の輝度の影響を無視できる.とは言えますが...
jbpb0

2022/10/12 13:39

> すみません,質問者の例示した画像のことでした. そういう意味でしたか 失礼しました > jbpb0さんの例示したデータではあまり有効に見えませんね. 私の回答の数値例は、標準化の計算がうまくいってることが一目で分かる、という観点で数値を選んでます
PondVillege

2022/10/12 13:53

> 私の回答の数値例は、標準化の計算がうまくいってることが一目で分かる、という観点で数値を選んでます 私も同様に,単純な数値例で検証することが多いですね, 数字を打つのもだるいのでいつもnp.arange(0, N * H * W * C).reshape(N, H, W, C)にしてやったりしています. 暇ついでに多くの画像でfeature-wise normalizationを試したところ,理想的にはどのピクセルの平均も分散も同じような値を取るのでdataset-wiseと変わらなくなることがわかりました. 質問者は2880件のデータを持っているので,ある程度理想状態には近づけば,feature-wiseも使えるかもしれませんね.

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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