国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

13個你一定來看看的PyTorch特性!

深度學習自然語言處理 ? 來源:ronghuaiyang(AI公園) ? 作者:MARCIN ZAB?OCKIMARCI ? 2021-04-19 09:08 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者:MARCIN ZAB?OCKIMARCIN ZAB?OCKI

編譯:ronghuaiyang(AI公園)

導讀

PyTorch使用上的13個特性,確實非常的有用。

PyTorch在學術界和工業界的應用研究中都獲得了很多關注。它是一個具有很大靈活性的深度學習框架,使用了大量的實用工具和函數來加快工作速度。PyTorch的學習曲線并不是那么陡峭,但在其中實現高效和干凈的代碼可能會很棘手。在使用它超過2年之后,以下是我最喜歡的PyTorch功能,我希望我一開始學習它就知道。

1. DatasetFolder

當學習PyTorch時,人們首先要做的事情之一是實現自己的某種Dataset 。這是一個低級錯誤,沒有必要浪費時間寫這樣的東西。通常,數據集要么是數據列表(或者是numpy數組),要么磁盤上的文件。所以,把數據在磁盤上組織好,要比寫一個自定義的Dataset來加載某種奇怪的格式更好。

分類器最常見的數據格式之一,是有一個帶有子文件夾的目錄,子文件夾表示類,子文件夾中的文件表示樣本,如下所示。

folder/class_0/file1.txt

folder/class_0/file2.txt

folder/class_0/。。.

folder/class_1/file3.txt

folder/class_1/file4.txt

folder/class_2/file5.txt

folder/class_2/。。.

有一個內置的方式來加載這類數據集,不管你的數據是圖像,文本文件或其他什么,只要使用‘DatasetFolder就可以了。令人驚訝的是,這個類是torchvision包的一部分,而不是核心PyTorch。這個類非常全面,你可以從文件夾中過濾文件,使用自定義代碼加載它們,并動態轉換原始文件。例子:

from torchvision.datasets import DatasetFolder

from pathlib import Path

# I have text files in this folder

ds = DatasetFolder(“/Users/marcin/Dev/tmp/my_text_dataset”,

loader=lambda path: Path(path).read_text(),

extensions=(“.txt”,), #only load .txt files

transform=lambda text: text[:100], # only take first 100 characters

# Everything you need is already there

len(ds), ds.classes, ds.class_to_idx

(20, [’novels‘, ’thrillers‘], {’novels‘: 0, ’thrillers‘: 1})

如果你在處理圖像,還有一個torchvision.datasets.ImageFolder類,它基于DatasetLoader,它被預先配置為加載圖像。

2. 盡量少用 .to(device) ,用 zeros_like / ones_like 之類的代替

我讀過很多來自GitHub倉庫的PyTorch代碼。最讓我惱火的是,幾乎在每個repo中都有許多*.to(device)行,它們將數據從CPUGPU轉移到其他地方。這樣的語句通常會出現在大量的repos或初學者教程中。我強烈建議盡可能少地實現這類操作,并依賴內置的PyTorch功能自動實現這類操作。到處使用.to(device)通常會導致性能下降,還會出現異常:

Expected object of device type cuda but got device type cpu

顯然,有些情況下你無法回避它,但大多數情況(如果不是全部)都在這里。其中一種情況是初始化一個全0或全1的張量,這在深度神經網絡計算損失的的時候是經常發生的,模型的輸出已經在cuda上了,你需要另外的tensor也是在cuda上,這時,你可以使用*_like操作符:

my_output # on any device, if it’s cuda then my_zeros will also be on cuda

my_zeros = torch.zeros_like(my_output_from_model)

在內部,PyTorch所做的是調用以下操作:

my_zeros = torch.zeros(my_output.size(), dtype=my_output.dtype, layout=my_output.layout, device=my_output.device)

所以所有的設置都是正確的,這樣就減少了代碼中出現錯誤的概率。類似的操作包括:

torch.zeros_like()

torch.ones_like()

torch.rand_like()

torch.randn_like()

torch.randint_like()

torch.empty_like()

torch.full_like()

3. Register Buffer ( nn.Module.register_buffer)

這將是我勸人們不要到處使用 .to(device) 的下一步。有時,你的模型或損失函數需要有預先設置的參數,并在調用forward時使用,例如,它可以是一個“權重”參數,它可以縮放損失或一些固定張量,它不會改變,但每次都使用。對于這種情況,請使用nn.Module.register_buffer 方法,它告訴PyTorch將傳遞給它的值存儲在模塊中,并將這些值隨模塊一起移動。如果你初始化你的模塊,然后將它移動到GPU,這些值也會自動移動。此外,如果你保存模塊的狀態,buffers也會被保存!

一旦注冊,這些值就可以在forward函數中訪問,就像其他模塊的屬性一樣。

from torch import nn

import torch

class ModuleWithCustomValues(nn.Module):

def __init__(self, weights, alpha):

super().__init__()

self.register_buffer(“weights”, torch.tensor(weights))

self.register_buffer(“alpha”, torch.tensor(alpha))

def forward(self, x):

return x * self.weights + self.alpha

m = ModuleWithCustomValues(

weights=[1.0, 2.0], alpha=1e-4

m(torch.tensor([1.23, 4.56]))

tensor([1.2301, 9.1201])

4. Built-in Identity()

有時候,當你使用遷移學習時,你需要用1:1的映射替換一些層,可以用nn.Module來實現這個目的,只返回輸入值。PyTorch內置了這個類。

例子,你想要在分類層之前從一個預訓練過的ResNet50獲取圖像表示。以下是如何做到這一點:

from torchvision.models import resnet50

model = resnet50(pretrained=True)

model.fc = nn.Identity()

last_layer_output = model(torch.rand((1, 3, 224, 224)))

last_layer_output.shape

torch.Size([1, 2048])

5. Pairwise distances: torch.cdist

下次當你遇到計算兩個張量之間的歐幾里得距離(或者一般來說:p范數)的問題時,請記住torch.cdist。它確實做到了這一點,并且在使用歐幾里得距離時還自動使用矩陣乘法,從而提高了性能。

points1 = torch.tensor([[0.0, 0.0], [1.0, 1.0], [2.0, 2.0]])

points2 = torch.tensor([[0.0, 0.0], [-1.0, -1.0], [-2.0, -2.0], [-3.0, -3.0]]) # batches don‘t have to be equal

torch.cdist(points1, points2, p=2.0)

tensor([[0.0000, 1.4142, 2.8284, 4.2426],

[1.4142, 2.8284, 4.2426, 5.6569],

[2.8284, 4.2426, 5.6569, 7.0711]])

沒有矩陣乘法或有矩陣乘法的性能,在我的機器上使用mm時,速度快了2倍以上。

%%timeit

points1 = torch.rand((512, 2))

points2 = torch.rand((512, 2))

torch.cdist(points1, points2, p=2.0, compute_mode=“donot_use_mm_for_euclid_dist”)

867μs±142μs per loop (mean±std. dev. of 7 run, 1000 loop each)

%%timeit

points1 = torch.rand((512, 2))

points2 = torch.rand((512, 2))

torch.cdist(points1, points2, p=2.0)

417μs±52.9μs per loop (mean±std. dev. of 7 run, 1000 loop each)

6. Cosine similarity: F.cosine_similarity

與上一點相同,計算歐幾里得距離并不總是你需要的東西。當處理向量時,通常余弦相似度是選擇的度量。PyTorch也有一個內置的余弦相似度實現。

import torch.nn.functional as F

vector1 = torch.tensor([0.0, 1.0])

vector2 = torch.tensor([0.05, 1.0])

print(F.cosine_similarity(vector1, vector2, dim=0))

vector3 = torch.tensor([0.0, -1.0])

print(F.cosine_similarity(vector1, vector3, dim=0))

tensor(0.9988)

tensor(-1.)

PyTorch中批量計算余弦距離

import torch.nn.functional as F

batch_of_vectors = torch.rand((4, 64))

similarity_matrix = F.cosine_similarity(batch_of_vectors.unsqueeze(1), batch_of_vectors.unsqueeze(0), dim=2)

similarity_matrix

tensor([[1.0000, 0.6922, 0.6480, 0.6789],

[0.6922, 1.0000, 0.7143, 0.7172],

[0.6480, 0.7143, 1.0000, 0.7312],

[0.6789, 0.7172, 0.7312, 1.0000]])

7. 歸一化向量: F.normalize

最后一點仍然與向量和距離有松散的聯系,那就是歸一化:通常是通過改變向量的大小來提高計算的穩定性。最常用的歸一化是L2,可以在PyTorch中按如下方式應用:

vector = torch.tensor([99.0, -512.0, 123.0, 0.1, 6.66])

normalized_vector = F.normalize(vector, p=2.0, dim=0)

normalized_vector

tensor([ 1.8476e-01, -9.5552e-01, 2.2955e-01, 1.8662e-04, 1.2429e-02])

在PyTorch中執行歸一化的舊方法是:

vector = torch.tensor([99.0, -512.0, 123.0, 0.1, 6.66])

normalized_vector = vector / torch.norm(vector, p=2.0)

normalized_vector

tensor([ 1.8476e-01, -9.5552e-01, 2.2955e-01, 1.8662e-04, 1.2429e-02])

在PyTorch中批量進行L2歸一化

batch_of_vectors = torch.rand((4, 64))

normalized_batch_of_vectors = F.normalize(batch_of_vectors, p=2.0, dim=1)

normalized_batch_of_vectors.shape, torch.norm(normalized_batch_of_vectors, dim=1) # all vectors will have length of 1.0

(torch.Size([4, 64]), tensor([1.0000, 1.0000, 1.0000, 1.0000]))

8. 線性層 + 分塊技巧 (torch.chunk)

這是我最近發現的一個有創意的技巧。假設你想把你的輸入映射到N個不同的線性投影中。你可以通過創建N個nn.Linear來做到這一點。或者你也可以創建一個單一的線性層,做一個向前傳遞,然后將輸出分成N塊。這種方法通常會帶來更高的性能,所以這是一個值得記住的技巧。

d = 1024

batch = torch.rand((8, d))

layers = nn.Linear(d, 128, bias=False), nn.Linear(d, 128, bias=False), nn.Linear(d, 128, bias=False)

one_layer = nn.Linear(d, 128 * 3, bias=False)

%%timeit

o1 = layers[0](batch)

o2 = layers[1](batch)

o3 = layers[2](batch)

289 μs ± 30.8 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit

o1, o2, o3 = torch.chunk(one_layer(batch), 3, dim=1)

202 μs ± 8.09 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

9. Masked select (torch.masked_select)

有時你只需要對輸入張量的一部分進行計算。給你一個例子:你想計算的損失只在滿足某些條件的張量上。為了做到這一點,你可以使用torch.masked_select,注意,當需要梯度時也可以使用這個操作。

data = torch.rand((3, 3)).requires_grad_()

print(data)

mask = data 》 data.mean()

print(mask)

torch.masked_select(data, mask)

tensor([[0.0582, 0.7170, 0.7713],

[0.9458, 0.2597, 0.6711],

[0.2828, 0.2232, 0.1981]], requires_grad=True)

tensor([[False, True, True],

[ True, False, True],

[False, False, False]])

tensor([0.7170, 0.7713, 0.9458, 0.6711], grad_fn=《MaskedSelectBackward》)

直接在tensor上應用mask

類似的行為可以通過使用mask作為輸入張量的 “indexer”來實現。

data[mask]

tensor([0.7170, 0.7713, 0.9458, 0.6711], grad_fn=《IndexBackward》)

有時,一個理想的解決方案是用0填充mask中所有的False值,可以這樣做:

data * mask

tensor([[0.0000, 0.7170, 0.7713],

[0.9458, 0.0000, 0.6711],

[0.0000, 0.0000, 0.0000]], grad_fn=《MulBackward0》)

10. 使用 torch.where來對tensors加條件

當你想把兩個張量結合在一個條件下這個函數很有用,如果條件是真,那么從第一個張量中取元素,如果條件是假,從第二個張量中取元素。

x = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0], requires_grad=True)

y = -x

condition_or_mask = x 《= 3.0

torch.where(condition_or_mask, x, y)

tensor([ 1., 2., 3., -4., -5.], grad_fn=《SWhereBackward》)

11. 在給定的位置給張量填入值(Tensor.scatter)

這個函數的用例如下,你想用給定位置下另一個張量的值填充一個張量。一維張量更容易理解,所以我將先展示它,然后繼續更高級的例子。

data = torch.tensor([1, 2, 3, 4, 5])

index = torch.tensor([0, 1])

values = torch.tensor([-1, -2, -3, -4, -5])

data.scatter(0, index, values)

tensor([-1, -2, 3, 4, 5])

上面的例子很簡單,但是現在看看如果將index改為index = torch.tensor([0, 1, 4])會發生什么:

data = torch.tensor([1, 2, 3, 4, 5])

index = torch.tensor([0, 1, 4])

values = torch.tensor([-1, -2, -3, -4, -5])

data.scatter(0, index, values)

tensor([-1, -2, 3, 4, -3])

為什么最后一個值是-3,這是反直覺的,對吧?這是PyTorch scatter函數的中心思想。index變量表示data張量的第i個值應該放在values張量的哪個位置。我希望下面的簡單python版的這個操作能讓你更明白:

data_orig = torch.tensor([1, 2, 3, 4, 5])

index = torch.tensor([0, 1, 4])

values = torch.tensor([-1, -2, -3, -4, -5])

scattered = data_orig.scatter(0, index, values)

data = data_orig.clone()

for idx_in_values, where_to_put_the_value in enumerate(index):

what_value_to_put = values[idx_in_values]

data[where_to_put_the_value] = what_value_to_put

data, scattered

(tensor([-1, -2, 3, 4, -3]), tensor([-1, -2, 3, 4, -3]))

2D數據的PyTorch scatter例子

始終記住,index的形狀與values的形狀相關,而index中的值對應于data中的位置。

data = torch.zeros((4, 4)).float()

index = torch.tensor([

[0, 1],

[2, 3],

[0, 3],

[1, 2]

])

values = torch.arange(1, 9).float().view(4, 2)

values, data.scatter(1, index, values)

(tensor([[1., 2.],

[3., 4.],

[5., 6.],

[7., 8.]]),

tensor([[1., 2., 0., 0.],

[0., 0., 3., 4.],

[5., 0., 0., 6.],

[0., 7., 8., 0.]]))

12. 在網絡中進行圖像插值 (F.interpolate)

當我學習PyTorch時,我驚訝地發現,實際上可以在前向傳遞中調整圖像(或任何中間張量),并保持梯度流。這種方法在使用CNN和GANs時特別有用。

# image from https://commons.wikimedia.org/wiki/File:A_female_British_Shorthair_at_the_age_of_20_months.jpg

img = Image.open(“。/cat.jpg”)

img

to_pil_image(

F.interpolate(to_tensor(img).unsqueeze(0), # batch of size 1

mode=“bilinear”,

scale_factor=2.0,

align_corners=False).squeeze(0) # remove batch dimension

看看梯度流是如何保存的:

F.interpolate(to_tensor(img).unsqueeze(0).requires_grad_(),

mode=“bicubic”,

scale_factor=2.0,

align_corners=False)

tensor([[[[0.9216, 0.9216, 0.9216, 。。., 0.8361, 0.8272, 0.8219],

[0.9214, 0.9214, 0.9214, 。。., 0.8361, 0.8272, 0.8219],

[0.9212, 0.9212, 0.9212, 。。., 0.8361, 0.8272, 0.8219],

。。.,

[0.9098, 0.9098, 0.9098, 。。., 0.3592, 0.3486, 0.3421],

[0.9098, 0.9098, 0.9098, 。。., 0.3566, 0.3463, 0.3400],

[0.9098, 0.9098, 0.9098, 。。., 0.3550, 0.3449, 0.3387]],

[[0.6627, 0.6627, 0.6627, 。。., 0.5380, 0.5292, 0.5238],

[0.6626, 0.6626, 0.6626, 。。., 0.5380, 0.5292, 0.5238],

[0.6623, 0.6623, 0.6623, 。。., 0.5380, 0.5292, 0.5238],

。。.,

[0.6196, 0.6196, 0.6196, 。。., 0.3631, 0.3525, 0.3461],

[0.6196, 0.6196, 0.6196, 。。., 0.3605, 0.3502, 0.3439],

[0.6196, 0.6196, 0.6196, 。。., 0.3589, 0.3488, 0.3426]],

[[0.4353, 0.4353, 0.4353, 。。., 0.1913, 0.1835, 0.1787],

[0.4352, 0.4352, 0.4352, 。。., 0.1913, 0.1835, 0.1787],

[0.4349, 0.4349, 0.4349, 。。., 0.1913, 0.1835, 0.1787],

。。.,

[0.3333, 0.3333, 0.3333, 。。., 0.3827, 0.3721, 0.3657],

[0.3333, 0.3333, 0.3333, 。。., 0.3801, 0.3698, 0.3635],

[0.3333, 0.3333, 0.3333, 。。., 0.3785, 0.3684, 0.3622]]]],

grad_fn=《UpsampleBicubic2DBackward1》)

13. 將圖像做成網格 (torchvision.utils.make_grid)

當使用PyTorch和torchvision時,不需要使用matplotlib或一些外部庫來復制粘貼代碼來顯示圖像網格。只要使用torchvision.utils.make_grid就行了。

from torchvision.utils import make_grid

from torchvision.transforms.functional import to_tensor, to_pil_image

from PIL import Image

img = Image.open(“。/cat.jpg”)

to_pil_image(

make_grid(

[to_tensor(i) for i in [img, img, img]],

nrow=2, # number of images in single row

padding=5 # “frame” size

英文原文:https://zablo.net/blog/post/pytorch-13-features-you-should-know/

編輯:jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7335

    瀏覽量

    94755
  • 圖像
    +關注

    關注

    2

    文章

    1096

    瀏覽量

    42325
  • pytorch
    +關注

    關注

    2

    文章

    813

    瀏覽量

    14842

原文標題:13個你一定要知道的PyTorch特性

文章出處:【微信號:zenRRan,微信公眾號:深度學習自然語言處理】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    ATtiny13/ATtiny13V:低功耗8位微控制器的強大之選

    的 ATtiny13 和 ATtiny13V 這兩款 8 位微控制器,看看它們究竟有哪些出色的特性與應用場景。 文件下載: ATTINY13
    的頭像 發表于 02-28 15:15 ?145次閱讀

    Pytorch 與 Visionfive2 兼容嗎?

    Pytorch 與 Visionfive2 兼容嗎? $ pip3 install torch torchvision torchaudio --index-url https
    發表于 02-06 08:28

    汽車級多路復用器TMUX13xxA - Q1:特性、應用與設計要點

    汽車級多路復用器TMUX13xxA - Q1:特性、應用與設計要點 在汽車電子和工業自動化等領域,對于高性能、高可靠性的信號切換和復用解決方案的需求日益增長。德州儀器(TI)的TMUX13
    的頭像 發表于 01-12 15:55 ?225次閱讀

    真不敢信,PCB板上就挪動了電阻,DDR3竟神奇變好了

    DDRx調試的問題我們經常會碰到,但PCB板上這個問題卻很初級,調了周都沒有解決,沒想到最后挪動了電阻就好了,不信大家來看看怎么回事!
    的頭像 發表于 01-05 15:40 ?232次閱讀
    真不敢信,PCB板上就挪動了<b class='flag-5'>一</b><b class='flag-5'>個</b>電阻,DDR3竟神奇變好了

    文讀懂!AI搜索既是趨勢也是未來,一定不可錯過的GEO機遇

    AI對搜索來說不是替代,而是進化,是搜索體驗的下一個階段。并已在眾多意想不到的場景中深入我們的生活,應用非常廣泛,到處都有AI搜索的影子。
    的頭像 發表于 12-12 17:38 ?2622次閱讀

    TMS320C6748 板卡設計中是否一定需要有SDRAM或者DDR

    的flash均無法進行讀寫。 麻煩給解釋下為什么會出現這種問題以及解決方案,是否一定需要外部加上SDRAM或者DDR?
    發表于 11-19 19:53

    AMD Vivado設計套件2025.1版本的功能特性

    成型設計套件能通過鍵式時序收斂,將設計從 RTL 階段推進到硬件階段,從而幫助縮短迭代周期。讓我們來看看該設計套件提供的功能特性
    的頭像 發表于 09-23 09:15 ?1617次閱讀
    AMD Vivado設計套件2025.1版本的功能<b class='flag-5'>特性</b>

    Arm方案 基于Arm架構的邊緣側設備(樹莓派或 NVIDIA Jetson Nano)上部署PyTorch模型

    本文將為展示如何在樹莓派或 NVIDIA Jetson Nano 等基于 Arm 架構的邊緣側設備上部署 PyTorch 模型。
    的頭像 發表于 07-28 11:50 ?2871次閱讀

    【選型】常見的遙控開關控制協議,看看哪種適合

    遙控開關,是種通過無線信號非接觸式遠程控制電路通斷的裝置,今天我們起聊聊常見的無線信號類別,看看哪種更適合?1.紅外遙控紅外型遙控,
    的頭像 發表于 07-17 19:34 ?1701次閱讀
    【選型】常見的遙控開關控制協議,<b class='flag-5'>看看</b>哪種適合<b class='flag-5'>你</b>?

    樹莓派復古游戲,會選哪一個

    絕佳選擇。下面我們將對這兩復古游戲發行版進行比較,助你決定哪個更適合自己。歷史與關鍵特性Batocera是款開源復古游戲發行版,于2016年作為Recalbox
    的頭像 發表于 06-16 16:56 ?1108次閱讀
    樹莓派復古游戲,<b class='flag-5'>你</b>會選哪<b class='flag-5'>一個</b>?

    機械工程師的九段位,現在處于哪層?

    學好數學、力學就能當機械工程師?太天真了!搞工程不是做研究,光會算應力應變可不行,機械原理、零件設計、材料工藝這些硬功夫一個都不能少。還要能夠將理論真正用到實踐中,才是最重要的。 對照以下標準,看看
    發表于 05-28 13:47

    為什么做遙感研究一定少不了地物光譜儀?

    什么作用? 句話概括:地物光譜儀提供了連接“像素”與“真實世界”的關鍵紐帶。 什么是地物光譜儀? 地物光譜儀(Field Spectroradiometer),顧名思義,是在地面對各種地物進行高光譜反射率測量的儀器。可以理解為它是
    的頭像 發表于 05-21 14:45 ?890次閱讀
    為什么做遙感研究<b class='flag-5'>一定</b>少不了地物光譜儀?

    功德+1,用小安派-Eyes-S1做一個電子木魚

    2024積德累功,心想事成!接下來看看如何用小安派-Eyes-S1做一個電子木魚。01GUI-Guider頁面設計先新建工程。直接進入UI設計界面,這里用到了兩
    的頭像 發表于 04-09 18:38 ?981次閱讀
    功德+1,用小安派-Eyes-S1做<b class='flag-5'>一個</b>電子木魚

    100節點測試藍牙Mesh?來看看效果

    100節點測試藍牙Mesh? 看看效果如何? 本次測試使用了安信可的泰凌TB系列模組 主要的測試的點在于配網的大致速度 丟包率以及最長響應時間 01藍牙Mesh簡介 藍牙Mesh是種先進
    的頭像 發表于 04-09 13:58 ?1303次閱讀
    100<b class='flag-5'>個</b>節點測試藍牙Mesh?<b class='flag-5'>來看看</b>效果

    假如你有塊樹莓派CM5,會用它來干什么?來看看這些異想天開的樹莓派項目!

    RaspberryPi處理器模塊5(CM5)是款功能強大的單板計算機,幾乎無所不能。與常規計算機不同,它專為與定制硬件完美配合而設計,因此您可以選擇所需的存儲空間、內存和無線功能。它體積小巧,用途
    的頭像 發表于 03-25 09:30 ?3043次閱讀
    假如你有<b class='flag-5'>一</b>塊樹莓派CM5,<b class='flag-5'>你</b>會用它來干什么?<b class='flag-5'>來看看</b>這些異想天開的樹莓派項目!