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

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

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

Chainerは、国産の深層学習フレームワークです。あらゆるニューラルネットワークをPythonで柔軟に書くことができ、学習させることが可能。GPUをサポートしており、複数のGPUを用いた学習も直感的に記述できます。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

解決済

1回答

1671閲覧

np.ones_like(self.data)の意味

tomomonX

総合スコア28

Chainer

Chainerは、国産の深層学習フレームワークです。あらゆるニューラルネットワークをPythonで柔軟に書くことができ、学習させることが可能。GPUをサポートしており、複数のGPUを用いた学習も直感的に記述できます。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

0クリップ

投稿2020/05/06 22:33

前提・実現したいこと

ゼロから作るdeep Learningフレームワーク編という本をみて、PytorchやChainerなどのフレームワークの勉強をしています。
dy/dx=(dy/dy)(dy/db)(db/da)(da/dx)として
逆伝搬でdy/dy(=1)からdy/dxを導き出すところを学んでいるところです。
コードを書くときに毎回dy/dyについての記述

Python

1y.grad = np.array(1.0)

をすると関数を使うユーザーとしては使い勝手が悪いため、backward関数に

Python

1 if self.grad is None: 2 self.grad = np.ones_like(self.data)

と記述すればいいらしいのですが、理由がよくわからないので教えてください。

本には「Variableのdataとgradのデータ型を同じにするためで、例えばdataの型が32ビットの浮動小数点であれば、gradの型も浮動小数点になります」と書いています。型が同じになるのはわかりましたが、

該当のソースコード

import numpy as np class Variable: def __init__(self, data): self.data = data self.grad = None self.creator = None def set_creator(self, func): self.creator = func def backward(self): ''' このコードをこの位置に入れればy.grad = np.array(1.0)を省くことができる。 if self.grad is None: self.grad = np.ones_like(self.data) '''      funcs = [self.creator] while funcs: f = funcs.pop() # 1. Get a function x, y = f.input, f.output # 2. Get the function's input/output x.grad = f.backward(y.grad) # 3. Call the function's backward if x.creator is not None: funcs.append(x.creator) class Function: def __call__(self, input): x = input.data y = self.forward(x) output = Variable(y) output.set_creator(self) self.input = input self.output = output return output def forward(self, x): raise NotImplementedError() def backward(self, gy): raise NotImplementedError() class Square(Function): def forward(self, x): y = x ** 2 return y def backward(self, gy): x = self.input.data gx = 2 * x * gy return gx class Exp(Function): def forward(self, x): y = np.exp(x) return y def backward(self, gy): x = self.input.data gx = np.exp(x) * gy return gx A = Square() B = Exp() C = Square() x = Variable(np.array(0.5)) a = A(x) b = B(a) y = C(b) # backward y.grad = np.array(1.0)#←毎回これを記述する手間を省きたい y.backward() print(x.grad)

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

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

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

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

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

guest

回答1

0

ベストアンサー

self.data の勾配を記録するには、self.data と同じ形状の配列が必要です。
numpy.ones_like() を使用すると、self.data と形状及び型が同じですべての要素が1の配列を簡単につくれるので、使っています。

python

1if self.grad is None: 2 self.grad = np.ones_like(self.data)

では、初期化を以下のようにしても、計算する際に、ブロードキャストによって self.data の形状に合わせられるので、問題はないですが、本来、self.grad に必要なのは、self.data と形状及び型が同じ配列なので、最初から numpy.ones_like() で確保するようになっているものと思います。

python

1if self.grad is None: 2 self.grad = np.array(1.0)

投稿2020/05/07 01:45

tiitoi

総合スコア21956

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

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

tomomonX

2020/05/07 12:19

ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問