寫練習時遇到的問題
1. 如何判斷一個張量的分佈服從[0,1)的均勻分佈?
t = torch.rand(5, 4)
怎麼證明這個是服從均勻分佈的?
解決:
均勻分佈的機率密度f(x)為:\(f(x) = \frac{1}{b-a}\), 其中x為[a, b],根據本例子為f(x) = 1, \(x \in [0,1]\)
均值\(\mu\)的計算為:$$\mu = \int_{a}^{b} x f(x) , dx$$, 所以,
\[\mu = \int_{0}^{1} x \cdot 1 \, dx = \int_{0}^{1} x \, dx = \left[\frac{x^2}{2}\right]_{0}^{1} = \frac{1}{2} = 0.5
\]
方差 \(\sigma^2\) 是根據以下公式計算的:
\[\sigma^2 = \int_{a}^{b} (x - \mu)^2 f(x) \, dx
\]
對於均勻分佈 \([0, 1)\):
\[\sigma^2 = \int_{0}^{1} (x - 0.5)^2 \cdot 1 \, dx = \int_{0}^{1} (x - 0.5)^2 \, dx
\]
分別計算三個部分的積分:
\[\int_{0}^{1} x^2 \, dx = \left[\frac{x^3}{3}\right]_{0}^{1} = \frac{1}{3}
\]
\[\int_{0}^{1} x \, dx = \left[\frac{x^2}{2}\right]_{0}^{1} = \frac{1}{2}
\]
\[\int_{0}^{1} \frac{1}{4} \, dx = \frac{1}{4} \cdot \left[x\right]_{0}^{1} = \frac{1}{4}
\]
因此,方差為:
\[\sigma^2 = \frac{1}{3} - \frac{1}{2} + \frac{1}{4} = \frac{4}{12} - \frac{6}{12} + \frac{3}{12} = \frac{1}{12}
\]
標準差 \(\sigma\) 是方差的平方根:
\[\sigma = \sqrt{\frac{1}{12}} \approx 0.2887
\]
寫出對應程式碼:
print(t.mean())
print(t.std())
"""
結果:
tensor(0.5417)
tensor(0.2662)
"""
是符合均勻分佈的, 得到解決
2. cat和stack的區別
GPT回答:
`torch.stack` 和 `torch.cat` 都是 PyTorch 中用於操作張量的函式,但它們的作用和行為有所不同。
### 1. `torch.cat`
- **功能**: `torch.cat` 是沿著已有的維度拼接張量。它不會建立新的維度,而是將多個張量在指定維度上連線起來。
- **引數**:
- `tensors`:要連線的張量列表。
- `dim`:沿著哪個維度進行拼接。
- **示例**:
```python
import torch
# 建立兩個形狀為 (2, 3) 的張量
t1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
t2 = torch.tensor([[7, 8, 9], [10, 11, 12]])
# 沿著第0維拼接
result = torch.cat((t1, t2), dim=0)
print(result)
```
輸出:
```
tensor([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
```
這裡 `t1` 和 `t2` 沿著第0維拼接,結果的形狀為 `(4, 3)`。
### 2. `torch.stack`
- **功能**: `torch.stack` 是沿著新維度拼接張量。與 `torch.cat` 不同,`torch.stack` 會建立一個新的維度。它不僅將張量拼接在一起,還會在指定的維度上增加一個新的維度。
- **引數**:
- `tensors`:要堆疊的張量列表。
- `dim`:新維度插入的位置。
- **示例**:
```python
import torch
# 建立兩個形狀為 (2, 3) 的張量
t1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
t2 = torch.tensor([[7, 8, 9], [10, 11, 12]])
# 沿著新維度堆疊
result = torch.stack((t1, t2), dim=0)
print(result)
```
輸出:
```
tensor([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
```
這裡 `t1` 和 `t2` 沿著新維度堆疊,結果的形狀為 `(2, 2, 3)`。
### 總結區別
- **維度變化**:
- `torch.cat`: 沿著指定的已有維度拼接張量,拼接後張量的維度不會增加。
- `torch.stack`: 在新維度上堆疊張量,拼接後張量的維度會增加一個。
- **使用場景**:
- 使用 `torch.cat` 可以在不改變張量的維度數量的情況下拼接張量,常用於資料擴充套件、合併等操作。
- 使用 `torch.stack` 可以在需要保留各張量獨立性(如生成批次)或需要增加新的維度的情況下堆疊張量。
由於torch.stack會有新的維度產生,需要reshape操作才能和cat的效果保持一致。
3. 記憶體共享
在 PyTorch 中,tensor 和 numpy 陣列之間可以相互轉換。轉換過程中有兩種情況需要注意:
共享記憶體:當你使用 tensor.numpy() 將一個 PyTorch 張量轉換為 NumPy 陣列時,得到的 NumPy 陣列與原始張量共享相同的記憶體。這意味著對其中任何一個的修改都會影響另一個。
不共享記憶體:當你直接使用 torch.tensor() 建立一個新的張量時,它會分配新的記憶體,不再與原來的張量或陣列共享記憶體。因此,此後對張量或陣列的修改不會影響另一個。
在進行梯度回傳時, 定義一個變數對網路權重進行賦值操作,發現更新後用==時權重沒有發生變化,但是實際上權重已經改變,由於記憶體共享的原因,造成更新的同時賦值的變數也被更新
利用。
x = tensor.clone()
建立一個記憶體相互獨立的變數