目次
1.3.1 他の既存のデータ構造から Tensor を変換および作成する
1.3.3 保存されたファイルから Tensor をロードする
1.4.2 柔軟な dtype と CPU/GPU の自由な切り替え
2.2.1 ndarray は並列化された操作 (ベクトル化された操作) をサポートします
2.2.2 効率は純粋な Python コードよりもはるかに高い
2.3.1 Numpy を使用して ndarray 配列を作成する
2.3.3 配列は ndarray の属性を通じて操作することもできます
2.3.4 指定された形状サイズとデータ型を 1 で満たした新しい配列を作成する
2.3.5 Python シーケンスの ndarray オブジェクトへの変換
2.3.7 反復オブジェクトを ndarray 配列に変換する
導入
ディープラーニングモデルを構築する過程では Tensor と Numpy が不可欠であり、しばしば 2 つのデータ構造の相互変換に直面します。
- これら 2 つのデータ構造の違いは正確には何でしょうか?
- 使用するデータ構造をいつ選択するか?
- 2 つのデータ構造間で変換するにはどうすればよいですか?
このペーパーでは、定義、アプリケーション シナリオ、変換方法などの複数の側面を通じて質問に答えます。
1 pytorch のテンソル
1.1 テンソルとは
Tensor は、深層学習における最も基本的かつ重要なデータ構造です。
- PyTorch にとって Tensor は、Numpy にとって配列、Pandas にとって DataFrame に相当し、どちらもフレームワーク全体の最下位レベルのデータ構造を構築します。
- Tensor は通常のデータ構造とは異なり、自動微分という非常に重要な機能を備えています。
定義: Tensor の英語の本来の意味は tensor であり、Pytorch 公式 Web サイトでは次のように紹介されています。
Tensor は 1 つのデータ型を含む高次元行列です。一般に、Tensor の高次元特性は、次の図に示すように、通常 3 次元以上の行列で記述されます。スカラー(スカラー)、数列をベクトル、複数の数列で構成される平面を行列、複数の平面で構成される立方体をテンソルと呼びます。もちろん、行列に 1 次元行列、2 次元行列、さらには多次元行列があるのと同じように、テンソルをテンソルと呼ぶために厳密に 3 次元以上に限定する必要はありません。深層学習のスカラー、ベクトル、行列は総称してテンソルと呼ばれます。
Tensor は PyTorch の独自の定義ではなく、TensorFlow などの多くの深層学習フレームワークで広く使用されているデータ構造です。
1.2 なぜ Tensor が必要なのか
PyTorchにおけるTensorはディープラーニングで広く使われているデータ構造であり、本質的には高次元の行列であり、NumPyにおける配列の高度化・高度化と理解しても過言ではありません。ただし、Tensor がサポートするいくつかの特別な機能により、Tensor は深層学習モデルとトレーニングのサポートに使用するとより便利です。
1.3 テンソルの作成方法
一般に、Tensor を作成するには 3 つの方法があります。
- 他の既存のデータ構造から Tensor を変換および作成する
- Tensor をランダムに初期化する
- 保存したファイルから Tensor をロードする
1.3.1 他の既存のデータ構造から Tensor を変換および作成する
これは実際のアプリケーションで最も一般的に使用される形式で、リストや NumPy 配列からデータを読み取り、新しい Tensor を生成するなど、データ セットをロードするためによく使用されます。この目標を達成するには、一般的に次の 2 つの方法が使用されます。
- トーチ.テンソル
- トーチ.テンソル
2 つの違いは、前者は tensor 関数 (t は小文字) を使用するのに対し、後者は Tensor クラス (T は大文字) を使用することです。2 つは、Tensor のデフォルト データ型の作成、パラメータの受け渡しと個々の詳細の処理のサポートです。
- 1 つ目は、作成された Tensor のデフォルトのデータ型が異なることです。
import torch
t1 = torch.tensor([1,2,3])
t2 = torch.Tensor([1,2,3])
print(t1, t2)
print(t1.dtype, t2.dtype)
実行中の表示は次のとおりです。
tensor([1, 2, 3]) tensor([1., 2., 3.])
torch.int64 torch.float32
- 次に、Tensor クラスを使用して整数を初期化して入力すると、この長さのすべてゼロの 1 次元テンソルが返されますが、tensor 関数はこの要素のみを含む 0 次元のテンソルを返します。
import torch
t1 = torch.tensor(3)
t2 = torch.Tensor(3)
print(t1, t2)
実行結果は次のようになります。
tensor(3) tensor([0., 0., 0.])
最初に言及する必要がある詳細が 1 つあります。Tensor クラスを使用してシーケンスを受信して Tensor を作成する場合、返されるデータ型は float 型です。これは、Tensor が FloatTensor と同等の形式であるためです。つまり、ByteTensor、IntTensor があるためです。 、LongTensor、DoubleTensor などのさまざまなデフォルトのデータ型。
既存のデータに基づいて、Tensor の他の 2 つの一般的に使用される関数を作成します。
- from_numpy
- as_tensor
2 つのメソッドと上記のメソッドの最大の違いは、返される Tensor が元のデータとメモリを共有するのに対し、前述の tensor 関数と Tensor クラスはコピー後に新しいオブジェクトを作成することです。
import torch
import numpy as np
n1 = np.array([1,2,3])
n2 = np.array([1,2,3])
n3 = np.array([1,2,3])
t1 = torch.tensor(n1)
t2 = torch.from_numpy(n2)
t3 = torch.as_tensor(n3)
print('t1:', t1)
print('t2:', t2)
print('t3:', t3)
n1[0] = 100
n2[0] = 100
n3[0] = 100
print('t1:', t1)
print('t2:', t2)
print('t2:', t3)
実行結果は次のようになります。
t1: tensor([1, 2, 3])
t2: tensor([1, 2, 3])
t3: tensor([1, 2, 3])
t1: tensor([1, 2, 3])
t2: tensor([100, 2, 3])
t2: tensor([100, 2, 3])
1.3.2 Tensor をランダムに初期化する
ランダム初期化は一般的に使用される形式であり、ニューラル ネットワーク モデルを構築する場合、モジュールの追加後にモジュールの重みが自動的にランダムに初期化されます。これらのメソッドは次の 2 つの形式に分類されます。
- torch.ones、torch.randn などの特定のタイプのテンソルを作成します。
- torch.ones_like、torch.randn_like など、既存の Tensor に基づいて、その形状と一致する特定のタイプの tensor を作成します。
import torch
func_name = [x for x in dir(torch) if x.endswith('like')]
print(func_name)
実行結果は次のようになります。
['empty_like', 'full_like', 'ones_like', 'rand_like', 'randint_like', 'randn_like', 'zeros_like']
PyTorch で完全に接続されたユニット Linear をランダムに構築します。これにより、デフォルトで対応する重み係数とオフセットが作成されます (通常、ネットワーク パラメーターは後続のモデル トレーニングに参加する必要があるため、デフォルトでは require_grad=True)。
import torch
linear = torch.nn.Linear(2,3)
print('weight:', linear.weight)
print('bias:', linear.bias)
実行結果は次のようになります。
weight: Parameter containing:
tensor([[-0.5380, -0.6481],
[ 0.0144, 0.0627],
[-0.6560, 0.0382]], requires_grad=True)
bias: Parameter containing:
tensor([-0.2800, 0.0235, -0.6940], requires_grad=True)
1.3.3 保存されたファイルから Tensor をロードする
PyTorch は、保存およびロードされるオブジェクトの形式を意図的に区別しません。訓練されたネットワークまたはデータにすることができます。これは、Python の pickle であり、torch.save と torch.load の 2 つの関数によって実現されます。保存されるファイルにサフィックス形式の要件はありません。一般的に使用されるサフィックス形式は、.pkl、.pth、および .pt です。この方法は、モデルや大規模なデータ セットを保存する場合によく使用されます。
import torch
t1 = torch.tensor([1,2,3,4,5])
torch.save(t1, 'tensor.pkl')
ret_t = torch.load('tensor.pkl')
print('ret_t', ret_t)
操作の結果は次のようになります。
ret_t tensor([1, 2, 3, 4, 5])
1.4 テンソルの特性
PyTorch が Python のリストや NumPy の配列を直接使用するのではなく、深層学習をサポートするために Tensor を定義している理由は、Tensor がいくつかの独自の機能を備えているためです。Tensor の主な特徴は次の 3 つの側面です。
- 豊富な共通操作機能
- 柔軟な dtype と CPU/GPU フリーのスイッチング ストレージ
- 自動勾配解決
1.4.1 豊富な共通機能操作
Tensor は本質的に数値要素で構成される高次元行列であり、深層学習のプロセスはさまざまな行列演算のプロセスであり、基本的なデータ構造として豊富な関数演算をサポートしています。
- Tensor 自体は tensor.max() や tensor.abs() などの関数を操作します。
- Tensor は、別のテンソルを追加するために tensor.add() が使用され、別のテンソルとの行列乗算を実行するために tensor.mm() が使用されるなど、他のテンソルに対して関連する操作を実行します。ここでの加算と乗算には、演算の 2 つのテンソル サイズに対する要件があります。
十分に豊富な関数操作をサポートすることに加えて、tensor の API 関数にはもう 1 つの重要な便利な機能があります: ほとんどの関数は 2 つのバージョンをサポートしています: tensor.abs() と tensor. abs_() など、下線付きバージョンと下線なしバージョン、どちらも Tensor を返します。ただし、同時に、下線付きのバージョンはインプレース操作に属します。つまり、それ自体のデータも呼び出し後に変更されます。
1.4.2 柔軟な dtype と CPU/GPU の自由な切り替え
Tensor の dtype の概念は、NumPy や Pandas での使用法に似ており、作成される Tensor のデータ構造を指定するために使用されます。PyTorch には、異なる長さの整数型と異なる長さの浮動小数点型を含む 10 の異なるデータ構造が定義されています。Tesor 全体のすべての要素は同じデータ型であり、数値型である必要があります (NumPy の配列にも要素が必要です)は同種ですが、文字列型をサポートします):
さまざまな数値データ型のサポートに加えて、Tensor のもう 1 つの大きな特徴は、さまざまなコンピューティング ユニット (CPU または GPU) をサポートしていることです。GPU アクセラレーションのサポートは、深層学習の大規模アプリケーションの鍵でもあります。CPU コンピューティング (メモリに保存されたデータ) と GPU コンピューティング (ビデオ メモリに保存されたデータ) を切り替えるために、Tensor は、次の 2 つの方法を含むストレージ デバイスの柔軟な構成をサポートしています。
- テンソルを作成するときは、デバイス パラメーターを通じて直接指定します。
- tensor.to() 関数を介して切り替えます。to() を使用してストレージデバイスとデータ型を切り替えることができます
さらに、dtype と device という 2 つの主要な機能に加えて、Tensor には実際にはレイアウトという 3 番目の機能があります。これには主に strded と sparse_coo が含まれており、この機能については通常、追加の考慮を必要としません。
1.4.3 自動勾配解決
テンソル自動勾配解決は深層学習の基礎であり、深層学習モデルの核心はニューロンの接続にあり、ニューロン間の接続の鍵となるのは各モジュールのパラメータであるネットワーク重みです。同じネットワーク構造でも異なるモデル アプリケーション値を達成できるのは、ネットワーク パラメーターが異なるためです。では、最適なネットワークパラメータを知るにはどうすればよいでしょうか? これが深層学習の最適化武器である勾配降下法であり、勾配降下法の大前提は自動勾配解をサポートすることです。
自動勾配解決をサポートするための Tensor の一般的なプロセスは次のとおりです。
- Tensor は grad ソリューションをサポートします。つまり、requires_grad=True
- 計算に参加する Tensor のプロセスに従って、Tensor と対応する演算関数はツリー構造 (または有向非巡回グラフ: DAG と呼ばれます) として記録され、計算の方向はリーフ ノードからルート ノードへです。
- ルート ノード テンソルとターゲット値に従って対応する差 (損失) を計算し、チェーン導出ルールを使用して勾配を逆に段階的に計算します (つまり、勾配の逆伝播)。
2 ナンピー
2.1 Numpyとは何ですか
Numerical Python の略である Numpy は、多次元配列オブジェクト (ndarray) と、これらの配列を操作するための関数のコレクション (function) で構成されるライブラリです。Numpy ライブラリを使用すると、配列に対して数学演算および関連する論理演算を実行できます。Numpy は Python の拡張パッケージであるだけでなく、Python 科学計算の基本パッケージでもあります。Numpy は、主に 1 次元または多次元配列の計算と処理に使用される多数の数学関数を提供し、一般的な配列および行列演算をサポートします。NumPy の最下層は主に C 言語で書かれているため、高速に数値計算を行うことができます。Numpy は、配列や行列の演算に非常に適したさまざまなデータ構造も提供します。
Numpy はオープンソース プロジェクトとして、多くの協力者によって共同開発および保守されており、データ サイエンス (ビッグ データの分析と処理、ビッグ データ ストレージ、データ キャプチャなどの分野を含むデータ サイエンス、DS と呼ばれる) の活発な発展に伴い、 Numpy と同様、SciPy (Python 科学計算ライブラリ)、Pandas (NumPy ベースのデータ処理ライブラリ) などのデータ分析ライブラリやその他のデータ分析ライブラリは大幅に成長しており、それらはすべてより単純な構文形式になっています。Numpy は通常、Matplotlib などと組み合わせて使用されます。
2.2 NumPy の利点は何ですか
2.2.1 ndarray は並列化された操作 (ベクトル化された操作) をサポートします
Numpy には並列計算機能が組み込まれており、システムに複数のコアがある場合、何らかの計算を行う際に numpy が自動的に並列計算を実行します。
2.2.2 効率は純粋な Python コードよりもはるかに高い
Numpy の最下層は C 言語で記述されており、内部で GIL (Global Interpreter Lock) のロックが解除されており、配列に対する演算速度が Python インタプリタの制限を受けないため、純粋な Python コードよりも効率が高くなります。
2.2.3 格納データアドレス連続
ndarray にデータを格納すると、データとデータのアドレスが連続するため、配列要素を一括して操作するのが高速になります。
ndarray のすべての要素の型は同じですが、Python リストの要素の型は任意であるため、要素を格納するときに ndarray のメモリは連続的であることができますが、Python のネイティブ リストはアドレス指定によってのみ次の要素を見つけることができます。一般的なパフォーマンスの点では Python のネイティブ リストほど良くありませんが、科学技術計算では、Numpy の ndarray は多くのループ ステートメントを節約でき、コードの使用法は Python のネイティブ リストよりもはるかに簡単です。
2.3 Numpy オブジェクトの作成方法
Numpy は、ndarray オブジェクトと呼ばれる n 次元配列オブジェクトを定義します。これは、同じ型の一連の要素で構成される配列コレクションです。配列内の各要素は同じサイズのメモリ ブロックを占有し、配列内の各要素はインデックス付けまたはスライスによって取得できます。ndarray オブジェクトには、要素のデータ型を記述する dtype 属性があります。ndarray オブジェクトは、配列のインデックス メカニズムを採用し、配列内の各要素をメモリ ブロックにマップし、特定のレイアウトに従ってメモリ ブロックを配置します。一般的に使用される 2 つのレイアウト方法、つまり行ごとまたは列ごとです。
ndarray オブジェクトは、Numpy の組み込み関数 array() を使用して作成できます。その構文形式は次のとおりです。
numpy.array(object, dtype = None, copy = True, order = None,ndmin = 0)
2.3.1 Numpy を使用して ndarray 配列を作成する
import numpy as np
a = np.array([1,2,3])
b = np.array([[1,2,3], [4,5,6]])
print(f'a:{a}')
print(f'type(a):{type(a)}')
print('b:{b}')
実行結果は次のようになります。
a:[1 2 3]
type(a):<class 'numpy.ndarray'>
b:{b}
2.3.2 配列の次元の確認と次元の変更
import numpy as np
a = np.array([[1,2], [3,4], [5,6]])
print(a.ndim)
print("old array:", a)
a = a.reshape(2,3)
print("new array:", a.ndim, a)
実行結果は次のようになります。
old array: [[1 2]
[3 4]
[5 6]]
new array: 2 [[1 2 3]
[4 5 6]]
2.3.3 配列は ndarray の属性を通じて操作することもできます
ndarray のプロパティ
import numpy as np
a = np.array([[1,2], [3,4], [5,6]])
print('a.shape:', a.shape)
print('a:', a)
a.shape = (2, 3)
print('a[2,3]:', a)
print('a[3,2]:', a.reshape(3, 2))
print('a.ndim:', a.ndim)
print('a.itemsize:', a.itemsize)
print('a.flags:', a.flags)
DD
a.shape: (3, 2)
a: [[1 2]
[3 4]
[5 6]]
a[2,3]: [[1 2 3]
[4 5 6]]
a[3,2]: [[1 2]
[3 4]
[5 6]]
a.ndim: 2
a.itemsize: 4
a.flags: C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
NDARRAY のタイプ
Numpy のデータ型識別コード。Numpy の各データ型には、次のように一意に識別される文字コードがあります。
i
- 整数b
- ブール値u
- 符号なし整数f
- 浮動小数点c
- 合成浮動小数点数m
- 時間指定からM
- 日付時刻O
- 物体S
- 弦U
- ユニコード文字列V
- 他のタイプの固定メモリ ブロック ( void )
通常、Numpy は SciPy パッケージと併用されますが、SciPy は Numpy をベースに多くの工学計算機能を追加した Numpy ライブラリの拡張版と考えることができます。
2.3.4 初期化されていない配列の作成
numpy.empty(shape, dtype = float, order = 'C')
numpy.empty() は初期化されていない配列を作成し、作成される配列の形状 (shape) とデータ型 (dtype) を指定できます。
参数:
shape:指定数组的形状;
dtype:数组元素的数据类型,默认值是值 float;
order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(“C”代表以行顺序存储,“F”则表示以列顺序存储)。
import numpy as np
n1 = np.empty([2, 2])
print(n1)
実行結果は次のようになります。
[[0.0e+000 5.4e-323]
[9.9e-324 9.9e-324]]
2.3.4 要素がすべて 0 の配列を作成する
numpy.zeros(shape,dtype=float,order="C")
この関数は、要素がすべて 0 である配列を作成するために使用され、配列の形状を指定することもできます。
参数:
shape:指定数组的形状;
dtype:数组元素的数据类型,默认值是值 float;
order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(“C”代表以行顺序存储,“F”则表示以列顺序存储)。
import numpy as np
n1 = np.zeros([2, 2])
print(n1)
実行結果は次のようになります。
[[0. 0.]
[0. 0.]]
2.3.4 指定された形状サイズとデータ型を 1 で満たした新しい配列を作成する
numpy.ones(shape, dtype = None, order = 'C')
指定された形状、サイズ、データ型の新しい配列を返します。新しい配列の各要素には 1 が入ります。
import numpy as np
n1 = np.ones([2, 2])
print(n1)
実行結果は次のとおりです
[[1. 1.]
[1. 1.]]
2.3.5 Python シーケンスの ndarray オブジェクトへの変換
numpy.asarray(sequence,dtype = None ,order = None )
asarray() は、Python シーケンスを ndarray オブジェクトに変換します。
参数:
sequence:接受一个 Python 序列,可以是列表或者元组;
dtype:可选参数,数组的数据类型,默认值是值 float;
order:指数组元素在计算机内存中的储存顺序,默认顺序是“C”(“C”代表以行顺序存储,“F”则表示以列顺序存储)。
import numpy as np
array = [1, 2, 3, 4, 5]
n1 = np.asarray(array)
print(n1)
print(type(n1))
実行結果は次のとおりです
[1 2 3 4 5]
<class 'numpy.ndarray'>
2.3.6 指定したバッファを使用して配列を作成する
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
指定されたバッファを使用して配列を作成することを示します。
参数:
buffer:将任意对象转换为流的形式读入缓冲区;
dtype:返回数组的数据类型,默认是 float32;
count:要读取的数据数量,默认为 -1 表示读取所有数据;
offset:读取数据的起始位置,默认为 0。
import numpy as np
data =b'hello world!'
res = np.frombuffer(data,dtype='S3',offset=0)
print(res)
実行結果は次のようになります。
[b'hel' b'lo ' b'wor' b'ld!']
2.3.7 反復オブジェクトを ndarray 配列に変換する
numpy.fromiter(iterable, dtype, count = -1)
反復オブジェクトを ndarray 配列に変換すると、その戻り値は 1 次元配列になります。
参数:
iterable:可迭代对象;
dtype:数组元素的数据类型,默认值是值 float;
count:读取的数据数量,默认为 -1,读取所有数据。
import numpy as np
iterable = (x * x*x for x in range(4))
n1 = np.fromiter(iterable, int)
print (n1)
実行結果は次のとおりです
[ 0 1 8 27]
2.3.8 指定された範囲の値を持つ配列を作成する
numpy.arange(start, stop, step, dtype)
参数:
start: 起始值,默认是 0。
stop: 终止值,注意生成的数组元素值不包含终止值。
step: 步长,默认为 1。
dtype: 可选参数,指定 ndarray 数组的数据类型。
import numpy as np
A = np.arange(5)
print(A)
print(type(A))
A = np.arange(1, 5)
print(A)
A = np.arange(1, 5, 2)
print(A)
A = np.arange(1, 5.2, 0.6)
print(A)
実行結果は次のとおりです
[0 1 2 3 4]
<class 'numpy.ndarray'>
[1 2 3 4]
[1 3]
[1. 1.6 2.2 2.8 3.4 4. 4.6 5.2]
2.3.9 指定した値の範囲内の配列を作成する
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数:
start:代表数值区间的起始值;
stop:代表数值区间的终止值;
num:表示数值区间内要生成多少个均匀的样本。默认值为 50;
endpoint:默认为 True,表示数列包含 stop 终止值,反之不包含;
retstep:默认为 True,表示生成的数组中会显示公差项,反之不显示;
dtype:代表数组元素值的数据类型。
import numpy as np
n1 = np.linspace(start = 0, stop = 1, num = 11)
n2 = np.linspace(start = 0, stop = 100, num = 11)
n3 = np.linspace(start = 1, stop = 5, num = 4, endpoint = False)
n4 = np.linspace(start = 0, stop = 100, num = 5, dtype = int)
print(n1)
print(n2)
print(n3)
print(n4)
実行結果は次のようになります。
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
[ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90. 100.]
[1. 2. 3. 4.]
[ 0 25 50 75 100]
2.3.10 比例配列の作成
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数:
start: 序列的起始值:base**start。
stop: 序列的终止值:base**stop。
num: 数值范围区间内样本数量,默认为 50。
endpoint: 默认为 True 包含终止值,反之不包含。
base: 对数函数的 log 底数,默认为10。
dtype: 可选参数,指定 ndarray 数组的数据类型。
対数空間では、開始点と終了点は 10 の累乗です。
import numpy as np
n1 = np.logspace(0,0,10)
n2 = np.logspace(0,9,10)
n3 = np.logspace(0,9,10,base=2)
print(n1)
print(n2)
print(n3)
実行結果は次のようになります。
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1.e+00 1.e+01 1.e+02 1.e+03 1.e+04 1.e+05 1.e+06 1.e+07 1.e+08 1.e+09]
[ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
2.4 Numpy 操作
2.4.1 配列要素のタイリング
numpy.ndarray. flat()
配列反復子を返します。その各要素は for ループで走査できます。
import numpy as np
a = np.arange(8).reshape(2, 4)
print ('a:', a)
for e in a.flat:
print (e, end=" ")
実行結果は次のようになります。
a: [[0 1 2 3]
[4 5 6 7]]
0 1 2 3 4 5 6 7
2.4.2 配列のコピーを 1 次元配列として返す
numpy.ndarray. flatten()
配列のコピーを 1 次元配列として返します。コピーを変更しても、元の配列には影響しません。
import numpy as np
a = np.arange(8).reshape(2, 4)
print(a)
print(a.flatten())
実行結果は次のようになります。
[[0 1 2 3]
[4 5 6 7]]
[0 1 2 3 4 5 6 7]
2.4.2 連続フラット配列への変換
numpy.ravel()
連続したフラット化された配列 (つまり、拡張された 1 次元配列) を返します。フラット化とは異なり、配列ビューを返します (ビューを変更すると元の配列に影響します)。
import numpy as np
a1, a2 = np.mgrid[1:4:1, 2:3:1]
print("a1:\n", a1, "\n", "a2:\n", a2)
n1 = a1.ravel()
n2 = a2.ravel()
print("n1:", n1)
print("n2:", n2)
sum = n1 + n2
print(sum)
実行結果は次のようになります。
a1:
[[1]
[2]
[3]]
a2:
[[2]
[2]
[2]]
n1: [1 2 3]
n2: [2 2 2]
[3 4 5]
2.4.3 Numpy のビット演算
import numpy as np
n1 = np.bitwise_and([11,7], [4,25])
n2 = np.bitwise_and(np.array([2,5,255]), np.array([3,14,16]))
n3 = np.bitwise_and([True, True], [False, True])
n4 = np.bitwise_or([11,7], [4,25])
n5 = np.bitwise_or(np.array([2,5,255]), np.array([3,14,16]))
n6 = np.bitwise_or([True, True], [False, True])
print(n1)
print(n2)
print(n3)
print(n4)
print(n5)
print(n6)
実行結果は次のようになります。
[0 1]
[ 2 4 16]
[False True]
[15 31]
[ 3 15 255]
[ True True]
2.4.4 算術演算
NumPy 配列の「加算、減算、乗算、除算」の算術演算は、それぞれ add()、subtract()、multiple()、divide() 関数に対応します。
- numpy.reciprocal() 関数は、配列内の各要素の逆数を取得し、それらを配列として返します。
- numpy.power() は、a 配列の要素を基数として、a に対応する b 配列の要素をべき乗し、最終的に 2 つの計算結果を配列の形式で返します。
- numpy.mod() は、2 つの配列の対応する位置にある要素を除算した後の剰余を返します。
import numpy as np
a = np.random.randint(9, size=(3, 3))
print("a =", a)
b = np.random.randint(9, size=(3, 3))
print("b =", b)
print("a + b =", np.add(a, b))
print("a - b =", np.subtract(a, b))
print("a x b =", np.multiply(a, b))
print("a / b =", np.divide(a, b))
実行結果は次のようになります。
a = [[8 0 2]
[7 8 4]
[3 5 1]]
b = [[2 3 5]
[1 8 3]
[4 1 2]]
a + b = [[10 3 7]
[ 8 16 7]
[ 7 6 3]]
a - b = [[ 6 -3 -3]
[ 6 0 1]
[-1 4 -1]]
a x b = [[16 0 10]
[ 7 64 12]
[12 5 2]]
a / b = [[4. 0. 0.4 ]
[7. 1. 1.33333333]
[0.75 5. 0.5 ]]
2.4.5 Numpy 行列演算
NumPy は行列ライブラリ モジュール numpy.matlib を提供し、このモジュールの関数は ndarray オブジェクトの代わりに行列オブジェクトを返します。行列は m 行 n 列 (m*n) の要素で構成され、行列の要素は数値、記号、または数式になります。
- numpy.matlib.empty() は空の行列を返します。これは非常に高速に作成できます。
- numpy.matlib.zeros() はゼロで埋められた行列を作成します。
- numpy.matlib.ones() は、1 で満たされた行列を作成します。
- numpy.matlib.eye() は、対角要素に 1、その他の要素に 0 を含む行列を返します。
- numpy.matlib.identity() この関数は、行列の対角要素が 1、その他の要素が 0 である、指定されたサイズの単位行列を返します。
- numpy.matlib.rand() は、乱数で満たされた指定された次元の行列を作成します。
import numpy as np
import numpy.matlib
print(np.matlib.empty((3, 4)))
print(np.matlib.zeros((3, 4)))
print(np.matlib.ones((3, 4)))
実行結果は次のようになります。
[[0.00000000e+000 nan 1.69759663e-313 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 0.00000000e+000 0.00000000e+000]]
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
2.4.5 2 つの行列の要素ごとの乗算
複数()
2 つの行列を要素ごとに乗算する関数。
import numpy as np
a1=np.array([[1,2], [3,4]], ndmin=2)
a2=np.array([[1,2], [3,4]], ndmin=2)
print(np.multiply(a1, a2))
[[ 1 4]
[ 9 16]]
2.4.6 2 つの配列の行列積
matmul() は、
2 つの配列の行列積を計算するために使用されます。
import numpy as np
a1=np.array([[1,2], [3,4]], ndmin=2)
a2=np.array([[1,2], [3,4]], ndmin=2)
print(np.matmul(a1, a2))
実行結果は次のようになります。
[[ 7 10]
[15 22]]
2.4.7 2 つの行列のドット積
dot()
関数は、2 つの行列のドット積を計算するために使用されます。
import numpy as np
a1=np.array([[1,2], [3,4]], ndmin=2)
a2=np.array([[1,2], [3,4]], ndmin=2)
print(np.dot(a1, a2))
[[ 7 10]
[15 22]]
2.4.8 2 つの行列の内積
numpy.inner() は、
配列間の内積を計算するために使用されます。
import numpy as np
n1=np.inner(np.array([1,2,3,4]),np.array([1,2,3,4]))
a1=np.array(([[1,2],[3,4]]))
a2=np.array(([[11,12],[13,14]]))
n2=np.inner(a1,a2)
print(n1)
print(n2)
実行結果は次のようになります。
30
[[35 41]
[81 95]]
2.4.9 線形行列方程式の解法
numpy.linalg.solve()
この関数は線形行列方程式を解くために使用され、線形方程式の解を行列の形式で表します。
連立方程式を解くx0 + 2 * x1 = 1
と、次のようになります3 * x0 + 5 * x1 = 2
。
import numpy as np
a = np.array([[1, 2], [3, 5]])
b = np.array([1, 2])
x = np.linalg.solve(a, b)
print(x)
実行結果は次のようになります。
[-1. 1.]
2.4.10 行列の逆行列の計算
numpy.linalg.inv()
この関数は行列の逆行列を計算するために使用され、逆行列と元の行列を乗算して単位行列を取得します。
import numpy as np
a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
n =np.linalg.inv(a)
print(a)
print(n)
実行結果は次のようになります。
[[[1. 2.]
[3. 4.]]
[[1. 3.]
[3. 5.]]]
[[[-2. 1. ]
[ 1.5 -0.5 ]]
[[-1.25 0.75]
[ 0.75 -0.25]]]
[[[-2. 2. ]
[ 4.5 -2. ]]
[[-1.25 2.25]
[ 2.25 -1.25]]]
3 Tensor と Numpy 間の相互変換
3.1 テンソルからNumpyへ
import numpy as np
import torch
t = torch.arange(1, 10).reshape(3, 3)
x = t.numpy()
print(f'a={t}')
print(f'b={x}')
実行結果は次のようになります。
a=tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
b=[[1 2 3]
[4 5 6]
[7 8 9]]
3.2 Numpy から Tensor へ
3.2.1 torch.tensor の使用
import numpy as np
import torch
a = np.random.normal(0, 1, (2, 3))
b = torch.tensor(a)
print(f'a={a}, b={b}')
実行結果は次のようになります。
a=[[ 1.77128009 2.02509013 0.38144148]
[ 1.14920329 -0.30733646 -1.20198951]]
b=tensor([[ 1.7713, 2.0251, 0.3814],
[ 1.1492, -0.3073, -1.2020]], dtype=torch.float64)
3.2.2 torch.from_numpy の使用
import numpy as np
import torch
a = np.random.normal(0, 1, (4, 5))
b = torch.from_numpy(a)
print(f'a={a}')
print(f'b={b}')
実行結果は次のようになります。
a=[[ 1.27357033 0.43722359 -0.74243293 -0.19531152 0.95053336]
[-0.52235811 0.95262418 -0.11157708 0.65592213 0.04188334]
[ 0.14932165 -0.40966126 0.09067062 0.3212764 -2.41411188]
[ 0.63391603 0.29742247 -0.43064322 1.08767221 -0.95699876]]
b=tensor([[ 1.2736, 0.4372, -0.7424, -0.1953, 0.9505],
[-0.5224, 0.9526, -0.1116, 0.6559, 0.0419],
[ 0.1493, -0.4097, 0.0907, 0.3213, -2.4141],
[ 0.6339, 0.2974, -0.4306, 1.0877, -0.9570]], dtype=torch.float64)
4 テンソルからその他へ
4.1 テンソル変換値
import torch
a = torch.tensor([1])
b = a.item()
print(f'a={a}')
print(f'b={b}')
実行結果は次のようになります。
a=tensor([1])
b=1
4.2 テンソルからリストへ
import torch
t1 = torch.arange(10)
t2 = t1.tolist()
print(f't1={t1}')
print(f't2={t2}')
実行結果は次のようになります。
t1=tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
t2=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4.3 テンソルからリスト テンソルへ
import torch
t1 = torch.arange(10)
t3 = list(t1)
print(f't1={t1}')
print(f't3={t3}')
実行結果は次のとおりです
t1=tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
t3=[tensor(0), tensor(1), tensor(2), tensor(3), tensor(4), tensor(5), tensor(6), tensor(7), tensor(8), tensor(9)]