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

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

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

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

Q&A

解決済

1回答

971閲覧

Python mask に関して複数の条件を指定する方法 - ReLU関数のカスタム法について

Sakana_pro

総合スコア1

Python

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

0グッド

0クリップ

投稿2022/07/05 04:52

編集2022/07/05 07:06

機械学習の勉強をするためPython でプログラミングしております。

活性化関数のRelu型関数に関して、条件を変えて色々試したくてプログラムを試みているのですがうまくいきません。

やりたいことは
1 ある以上の値になった場合に0を返す

2ある以上の値になった場合は関数の上限を固定する

3ある以上の値になった場合、値を変更する=例えばランダム性を生じる

などです。某有名書のコードをそのまま使っておりまして,Reluの順向きな発火に関しては、 Self.mask を組み込んでおります。

**
https://github.com/oreilly-japan/deep-learning-from-scratch
こちらの ch05 の二層の実行プログラム
https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/ch05/two_layer_net.py
の背景にあるコードを編集してみようと思っています。
https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/common/layers.py

こちらのClass Relu, が該当コードとなります。
**

Python

1def forward(self, x): 2 self.mask = (x <= 0) 3 out = x.copy() 4 out[self.mask] = 0 5

このようなコードで通常のReluの振る舞いを定義しております。

ここで0以下に加えて、500以上の値を取った時に0の値を出力したいのですが、

Python

1def forward(self, x): 2 self.mask = (x <= 0) & (x > 500) 3 out = x.copy() 4 out[self.mask] = 0

もしくは

Python

1def forward(self, x): 2 self.mask = (x <= 0) | (x > 500) 3 out = x.copy() 4 out[self.mask] = 0

で目的の指定ができるかと思っているのですが、これで良いのでしょうか。試していて動かしても正しく動いているように思えません。
正しく設定する方法をご教示いただけましたら大変ありがたいです。

また2はRelu6

ReLU6(x)=min(max(0,x),6)

などがその例かと思うのですが、こちらを上記のfoward の関数の中にどのように取り込めばよいかもアドバイスいただけますと幸いです。

3に関しては具体的なアイデアはまだないのですが、例えばある一定上の値になった場合にはある一定までからゼロのランダムをとる、 というものが記述できないかと思っております。

ぜひお力を頂きたく思います。

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

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

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

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

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

can110

2022/07/05 05:15

コードは断片ではなく他の人が検証、実行可能な状態でコードプロックで囲んで提示ください(例えばxの型が不明です) また、とくに問題なければ参考図書、サイト名は明示ください。 そのうえで、実際に単純データ例で試してみれば正しいかは判断できると思うのですが、いかがでしょうか。
Sakana_pro

2022/07/05 05:33

ご確認ありがとうございました。こちらゼロから作るディープラーニングのMNIST画像認識に関するコードとなります。 https://github.com/oreilly-japan/deep-learning-from-scratch こちらの ch05 の二層の実行プログラム https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/ch05/two_layer_net.py の背景にあるコードを編集してみようと思っています。 https://github.com/oreilly-japan/deep-learning-from-scratch/blob/master/common/layers.py こちらのClass Relu, が該当コードとなります。 def forward(self, x): self.mask = (x <= 0) out = x.copy() out[self.mask] = 0 xはnumpy array として格納された各要素です。 よろしくお願いいたします。
can110

2022/07/05 05:59

ここは依頼のための欄であり、目につきにくくもあるので質問本文を修正ください。
quickquip

2022/07/05 06:18

コード部分はコードの入力機能を使って普通に読めるようにしましょう。 https://teratail.com/help/question-tips#questionTips35 これで良いのでしょうか。 と質問していますが思った通りに動かなくて聞いているのか、思った通りに動いたけど聞いているのか不明なせいで、何を聞きたいのかふんわりしているという印象でした。何が問題になっているのか分かりません。 (内容的に私が回答することはないと思いますが気になったので。1と3は逆伝搬どうするつもりなんだろうみたいな疑問はありますが……)
Sakana_pro

2022/07/05 07:08

修正対応いたしました。ご指摘ありがとうございました。
Sakana_pro

2022/07/05 07:16

1に関しましては Backward を def backward(self, dout): dout[self.mask] = 0 dx = dout return dx のように処置してますので、mask で条件付けして、0以下と500以上は微分ゼロ、その他は1で良いのかと思っておりました。 確かに3は微分が不明な感じがします。
guest

回答1

0

ベストアンサー

まず元のReLU関数において
順伝播は

PlainText

1x if(x>0) 20 if(x<=0)

逆伝播は上の微分した結果なので

PlainText

11 if(x>0) 20 if(x<=0)

となります。
よって1 ある以上の値になった場合に0を返す関数において
順伝播は

PlainText

10 if(x>=500) 2x if(0<x<500) 30 if(x<=0)

逆伝播は上の微分した結果なので

PlainText

10 if(x>=500) 21 if(0<x<500) 30 if(x<=0)

となればよいです。

以上を踏まえ参考元のReLU関数を見てみます。

Python

1class Relu: 2 def __init__(self): 3 self.mask = None 4 5 def forward(self, x): 6 self.mask = (x <= 0) 7 out = x.copy() 8 out[self.mask] = 0 9 10 return out 11 12 def backward(self, dout): 13 dout[self.mask] = 0 14 dx = dout 15 16 return dx

上記ではmask(x<=0)で作成し、その条件に合致する部分に0をセットしています。
これを参考にするとの関数のmaskは「ある値以上 または 0以下」という条件とすればよいことが分かります。

2、3も同じように逆伝播(微分した結果)を定式化したうえでコードに落とし込めばよいです。
(が、3は定式化できるか??)
参考:【ゼロから作るDeep Learning】5章 誤差逆伝播法

投稿2022/07/05 07:50

can110

総合スコア38266

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

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

Sakana_pro

2022/07/05 09:08 編集

ご回答に従ってコードを作ってみました class Relu: def __init__(self): self.mask = None self.mask2 = None def forward(self, x): self.mask = (x <= 0) self.mask2 = (x < 500) out = 0 out[self.mask] = 0 out[self.mask2] = x.copy() return out def backward(self, dout): dout[self.mask] = 0 dx = 0 dout[self.mask2] = 1 return dx こういうことかと思ったのですが、backward は不明でかつ、走らせますと今度は、 **out[self.mask] = 0 TypeError: 'int' object does not support item assignment ** とエラーが出てしまいます。どのように書くべきかご教示いただけますととても助かります。 よろしくお願いいたします。
can110

2022/07/05 09:05

とりあえずout=0という部分の意図が不明です。 まずはカスタムの前に、もとのReLUクラスの各関数の動きを書籍とともに理解するように努めた方がよいかと思います。
Sakana_pro

2022/07/05 09:39

プログラム走りました。これで良いのかと思いました。 Class Relu: def __init__(self): self.mask = None self.mask2 = None def forward(self, x): self.mask = (x <= 0) self.mask2 = (x >= 500) out = x.copy() out[self.mask] = 0 out[self.mask2] = 0 return out def backward(self, dout): dout[self.mask] = 0 dx = dout dout[self.mask2] = 0 return dx こちらで正しくできているとしたら、非常にハッピーな実験結果となります。ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問