0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

PyTorch構(gòu)建自己一種易用的計(jì)算圖結(jié)構(gòu)

jf_pmFSk4VX ? 來(lái)源:GiantPandaCV ? 2023-02-01 14:26 ? 次閱讀

PNNX

PNNX項(xiàng)目 PyTorch Neural Network eXchange(PNNX)是PyTorch模型互操作性的開放標(biāo)準(zhǔn).

PNNX為PyTorch提供了一種開源的模型格式, 它定義了與PyTorch相匹配的數(shù)據(jù)流圖和運(yùn)算操作, 我們的框架在PNNX之上封裝了一層更加易用和簡(jiǎn)單的計(jì)算圖格式. PyTorch訓(xùn)練好一個(gè)模型之后, 然后模型需要轉(zhuǎn)換到PNNX格式, 然后PNNX格式我們?cè)偃プx取, 形成計(jì)算圖.

PyTorch到我們計(jì)算圖?

PNNX幫我做了很多的圖優(yōu)化、算子融合的工作, 所以底層的用它PNNX的話, 我們可以吸收?qǐng)D優(yōu)化的結(jié)果, 后面推理更快.

但是我們不直接在項(xiàng)目中用PNNX, 因?yàn)閯e人的工作和自己推理框架開發(fā)思路總是有不同的. 所以在這上面封裝, 又快速又好用方便, 符合自己的使用習(xí)慣. PNNX的使用方法, 我們只是去讀取PNNX導(dǎo)出的模型, 然后構(gòu)建自己一種易用的計(jì)算圖結(jié)構(gòu).

PNNX的格式定義

PNNX由操作數(shù)operand(運(yùn)算數(shù))和operator(運(yùn)算符號(hào)), PNNX::Graph用來(lái)管理和操作這兩者.

操作數(shù)(operand), 也可以通過操作數(shù)來(lái)方向訪問到這個(gè)數(shù)字的產(chǎn)生者和使用者Customer

代碼鏈接

Operand

定義鏈接

Operand有以下幾個(gè)部分組成:

Producer: 類型是operator, 表示產(chǎn)生了這個(gè)操作數(shù)(operand)的運(yùn)算符(operator). 也就是說這個(gè)操作數(shù)(operand)是Producer的輸出.

比如Producer是有個(gè)Add, Operand就是對(duì)應(yīng)的Add結(jié)果.

Customer:類型是operator, 表示需要這個(gè)操作數(shù)是下一個(gè)操作的運(yùn)算符(operator)的輸入. 值得注意的是生產(chǎn)者Producer作為產(chǎn)生這個(gè)操作數(shù)的operator只能有一個(gè), 而消費(fèi)者Customer可以有多個(gè), 消費(fèi)者將當(dāng)前的操作數(shù)Operand作為輸入.

Name: 類型是std::string, 表示這個(gè)操作數(shù)的名稱.

Shape: 類型是std::vector , 用來(lái)表示操作數(shù)的大小.

Operator

定義鏈接

operator有以下幾個(gè)部分組成:

Inputs: 類型為std::vector, 表示這個(gè)運(yùn)算符計(jì)算過程中所需要的輸入操作數(shù)(operand)

Outputs: 類型為std::vector, 表示這個(gè)運(yùn)算符計(jì)算過程中得到的輸出操作數(shù)(operand)

Type, Name 類型均為std::string, 分別表示運(yùn)算符號(hào)的類型和名稱

Params, 類型為std::map,用于存放該運(yùn)算符的所有參數(shù)(例如對(duì)應(yīng)Convolution operator的params中將存放stride, padding, kernel size等信息)

Attrs, 類型為std::map, 用于存放運(yùn)算符號(hào)所需要的具體權(quán)重屬性(例如對(duì)應(yīng)Convolution operator的attrs中就存放著卷積的權(quán)重和偏移量)

我們對(duì)PNNX的封裝

對(duì)Operands(運(yùn)算數(shù))的封裝

structRuntimeOperand{
std::stringname;///操作數(shù)的名稱
std::vectorshapes;///操作數(shù)的形狀
std::vector>>datas;///存儲(chǔ)操作數(shù)
RuntimeDataTypetype=RuntimeDataType::kTypeUnknown;///操作數(shù)的類型,一般是float
};

對(duì)Operator(運(yùn)算符)的封裝

對(duì)PNNX::operator的封裝是RuntimeOperator, 下面會(huì)講具體的PNNX到KuiperInfer計(jì)算圖的轉(zhuǎn)換過程.

///計(jì)算圖中的計(jì)算節(jié)點(diǎn)
structRuntimeOperator{
~RuntimeOperator();
std::stringname;///運(yùn)算符號(hào)節(jié)點(diǎn)的名稱
std::stringtype;///運(yùn)算符號(hào)節(jié)點(diǎn)的類型
std::shared_ptrlayer;///節(jié)點(diǎn)對(duì)應(yīng)的計(jì)算Layer

std::vectoroutput_names;///運(yùn)算符號(hào)的輸出節(jié)點(diǎn)名稱
std::shared_ptroutput_operands;///運(yùn)算符號(hào)的輸出操作數(shù)

std::map>input_operands;///運(yùn)算符的輸入操作數(shù)
std::vector>input_operands_seq;///運(yùn)算符的輸入操作數(shù),順序排列

std::mapparams;///算子的參數(shù)信息
std::map>attribute;///算子的屬性信息,內(nèi)含權(quán)重信息
};

從PNNX計(jì)算圖到KuiperInfer計(jì)算圖的過程

本節(jié)代碼鏈接

1. 加載PNNX的計(jì)算圖

intload_result=this->graph_->load(param_path_,bin_path_);

2. 獲取PNNX計(jì)算圖中的運(yùn)算符(operators)

std::vectoroperators=this->graph_->ops;
if(operators.empty()){
LOG(ERROR)<

3. 遍歷PNNX計(jì)算圖中的運(yùn)算符, 構(gòu)建KuiperInfer計(jì)算圖

for(constpnnx::Operator*op:operators){
...
}

4. 初始化RuntimeOperator的輸入

初始化RuntimeOperator中的RuntimeOperator.input_operands和RuntimeOperator.input_operands_seq兩個(gè)屬性.

通過解析pnnx的計(jì)算圖來(lái)初始化KuiperInfer RuntimeOperator中的輸入部分. 簡(jiǎn)單來(lái)說就是從pnnx::inputs轉(zhuǎn)換得到KuiperInfer::inputs

structRuntimeOperator{
///本過程要初始化的兩個(gè)屬性
std::map>input_operands;///運(yùn)算符的輸入操作數(shù)
std::vector>input_operands_seq;///運(yùn)算符的輸入操作數(shù),順序排列
...
}

從PNNX::Input到KuiperInfer::Input的轉(zhuǎn)換過程, 代碼鏈接

constpnnx::Operator*op=...
conststd::vector&inputs=op->inputs;
if(!inputs.empty()){
InitInputOperators(inputs,runtime_operator);
}
....
voidRuntimeGraph::InitInputOperators(conststd::vector&inputs,
conststd::shared_ptr&runtime_operator){
//遍歷輸入pnnx的操作數(shù)類型(operands),去初始化KuiperInfer中的操作符(RuntimeOperator)的輸入.
for(constpnnx::Operand*input:inputs){
if(!input){
continue;
}
//得到pnnx操作數(shù)對(duì)應(yīng)的生產(chǎn)者(類型是pnnx::operator)
constpnnx::Operator*producer=input->producer;
//初始化RuntimeOperator的輸入runtime_operand
std::shared_ptrruntime_operand=std::make_shared();
//賦值runtime_operand的名稱和形狀
runtime_operand->name=producer->name;
runtime_operand->shapes=input->shape;

switch(input->type){
case1:{
runtime_operand->type=RuntimeDataType::kTypeFloat32;
break;
}
case0:{
runtime_operand->type=RuntimeDataType::kTypeUnknown;
break;
}
default:{
LOG(FATAL)<type;
}
}
//runtime_operand放入到KuiperInfer的運(yùn)算符中
runtime_operator->input_operands.insert({producer->name,runtime_operand});
runtime_operator->input_operands_seq.push_back(runtime_operand);
}
}

5. 初始化RuntimeOperator中的輸出

初始化RuntimeOperator.output_names屬性. 通過解析PNNX的計(jì)算圖來(lái)初始化KuiperInfer Operator中的輸出部分.代碼鏈接

簡(jiǎn)單來(lái)說就是從PNNX::outputs到KuiperInfer::output

voidRuntimeGraph::InitOutputOperators(conststd::vector&outputs,
conststd::shared_ptr&runtime_operator){
for(constpnnx::Operand*output:outputs){
if(!output){
continue;
}
constauto&consumers=output->consumers;
for(constauto&c:consumers){
runtime_operator->output_names.push_back(c->name);
}
}
}

6. 初始化RuntimeOperator的權(quán)重(Attr)屬性

KuiperInfer::RuntimeAttributes. Attributes中存放的是operator計(jì)算時(shí)需要的權(quán)重屬性, 例如Convolution Operator中的weights和bias.

//初始化算子中的attribute(權(quán)重)
constpnnx::Operator*op=...
conststd::map&attrs=op->attrs;
if(!attrs.empty()){
InitGraphAttrs(attrs,runtime_operator);
}

代碼鏈接

voidRuntimeGraph::InitGraphAttrs(conststd::map&attrs,
conststd::shared_ptr&runtime_operator){
for(constauto&pair:attrs){
conststd::string&name=pair.first;
//1.得到pnnx中的Attribute
constpnnx::Attribute&attr=pair.second;
switch(attr.type){
case1:{
//2.根據(jù)Pnnx的Attribute初始化KuiperInferOperator中的Attribute
std::shared_ptrruntime_attribute=std::make_shared();
runtime_attribute->type=RuntimeDataType::kTypeFloat32;
//2.1賦值權(quán)重weight(此處的data是std::vector類型)
runtime_attribute->weight_data=attr.data;
runtime_attribute->shape=attr.shape;
runtime_operator->attribute.insert({name,runtime_attribute});
break;
}
default:{
LOG(FATAL)<

7. 初始化RuntimeOperator的參數(shù)(Param)屬性

簡(jiǎn)單來(lái)說就是從pnnx::Params去初始化KuiperInfer::Params

conststd::map¶ms=op->params;
if(!params.empty()){
InitGraphParams(params,runtime_operator);
}

KuiperInfer::RuntimeParameter有多個(gè)派生類構(gòu)成, 以此來(lái)對(duì)應(yīng)中多種多樣的參數(shù), 例如ConvOperator中有std::string類型的參數(shù), padding_mode, 也有像uint32_t類型的kernel_size和padding_size參數(shù), 所以我們需要以多種參數(shù)類型去支持他.

換句話說, 一個(gè)KuiperInfer::Params, param可以是其中的任意一個(gè)派生類, 這里我們利用了多態(tài)的特性. KuiperInfer::RuntimeParameter具有多種派生類, 如下分別表示為Int參數(shù)和Float參數(shù), 他們都是RuntimeParameter的派生類.

std::mapparams;///算子的參數(shù)信息
//用指針來(lái)實(shí)現(xiàn)多態(tài)

structRuntimeParameter{///計(jì)算節(jié)點(diǎn)中的參數(shù)信息
virtual~RuntimeParameter()=default;

explicitRuntimeParameter(RuntimeParameterTypetype=RuntimeParameterType::kParameterUnknown):type(type){

}
RuntimeParameterTypetype=RuntimeParameterType::kParameterUnknown;
};
///int類型的參數(shù)
structRuntimeParameterInt:publicRuntimeParameter{
RuntimeParameterInt():RuntimeParameter(RuntimeParameterType::kParameterInt){

}
intvalue=0;
};
///float類型的參數(shù)
structRuntimeParameterFloat:publicRuntimeParameter{
RuntimeParameterFloat():RuntimeParameter(RuntimeParameterType::kParameterFloat){

}
floatvalue=0.f;
};

從PNNX::param到RuntimeOperator::param的轉(zhuǎn)換過程.代碼鏈接

voidRuntimeGraph::InitGraphParams(conststd::map¶ms,
conststd::shared_ptr&runtime_operator){
for(constauto&pair:params){
conststd::string&name=pair.first;
constpnnx::Parameter¶meter=pair.second;
constinttype=parameter.type;
//根據(jù)PNNX的Parameter去初始化KuiperInfer::RuntimeOperator中的Parameter
switch(type){
caseint(RuntimeParameterType::kParameterUnknown):{
RuntimeParameter*runtime_parameter=newRuntimeParameter;
runtime_operator->params.insert({name,runtime_parameter});
break;
}
//在這應(yīng)該使用派生類RuntimeParameterBool
caseint(RuntimeParameterType::kParameterBool):{
RuntimeParameterBool*runtime_parameter=newRuntimeParameterBool;
runtime_parameter->value=parameter.b;
runtime_operator->params.insert({name,runtime_parameter});
break;
}
//在這應(yīng)該使用派生類RuntimeParameterInt
caseint(RuntimeParameterType::kParameterInt):{
RuntimeParameterInt*runtime_parameter=newRuntimeParameterInt;
runtime_parameter->value=parameter.i;
runtime_operator->params.insert({name,runtime_parameter});
break;
}

caseint(RuntimeParameterType::kParameterFloat):{
RuntimeParameterFloat*runtime_parameter=newRuntimeParameterFloat;
runtime_parameter->value=parameter.f;
runtime_operator->params.insert({name,runtime_parameter});
break;
}

caseint(RuntimeParameterType::kParameterString):{
RuntimeParameterString*runtime_parameter=newRuntimeParameterString;
runtime_parameter->value=parameter.s;
runtime_operator->params.insert({name,runtime_parameter});
break;
}

caseint(RuntimeParameterType::kParameterIntArray):{
RuntimeParameterIntArray*runtime_parameter=newRuntimeParameterIntArray;
runtime_parameter->value=parameter.ai;
runtime_operator->params.insert({name,runtime_parameter});
break;
}

caseint(RuntimeParameterType::kParameterFloatArray):{
RuntimeParameterFloatArray*runtime_parameter=newRuntimeParameterFloatArray;
runtime_parameter->value=parameter.af;
runtime_operator->params.insert({name,runtime_parameter});
break;
}
caseint(RuntimeParameterType::kParameterStringArray):{
RuntimeParameterStringArray*runtime_parameter=newRuntimeParameterStringArray;
runtime_parameter->value=parameter.as;
runtime_operator->params.insert({name,runtime_parameter});
break;
}
default:{
LOG(FATAL)<

8. 初始化成功

將通過如上步驟初始化好的KuiperInfer::RuntimeOperator存放到一個(gè)vector中

this->operators_.push_back(runtime_operator);

驗(yàn)證我們的計(jì)算圖

我們先準(zhǔn)備好了如下的一個(gè)計(jì)算圖(準(zhǔn)備過程不是本節(jié)的重點(diǎn), 讀者直接使用即可), 存放在tmp目錄中, 它由兩個(gè)卷積, 一個(gè)Add(expression)以及一個(gè)最大池化層組成.

3685b1f6-98fa-11ed-bfe3-dac502259ad0.png

TEST(test_runtime,runtime1){
usingnamespacekuiper_infer;
conststd::string¶m_path="./tmp/test.pnnx.param";
conststd::string&bin_path="./tmp/test.pnnx.bin";
RuntimeGraphgraph(param_path,bin_path);
graph.Init();
constautooperators=graph.operators();
for(constauto&operator_:operators){
LOG(INFO)<type<name;
}
}

如上為一個(gè)測(cè)試函數(shù), Init就是我們剛才分析過的一個(gè)函數(shù), 它定義了從PNNX計(jì)算圖到KuiperInfer計(jì)算圖的過程.

最后的輸出

I202301071133.03383856358test_main.cpp:13]Starttest...
I202301071133.03441156358test_runtime1.cpp:17]type:pnnx.Inputname:pnnx_input_0
I202301071133.03442156358test_runtime1.cpp:17]type:nn.Conv2dname:conv1
I202301071133.03442556358test_runtime1.cpp:17]type:nn.Conv2dname:conv2
I202301071133.03443056358test_runtime1.cpp:17]type:pnnx.Expressionname:pnnx_expr_0
I202301071133.03443556358test_runtime1.cpp:17]type:nn.MaxPool2dname:max
I202301071133.03444056358test_runtime1.cpp:17]type:pnnx.Outputname:pnnx_output_0

可以看出, Init函數(shù)最后得到的結(jié)果和圖1中定義的是一致的. 含有兩個(gè)Conv層, conv1和conv2, 一個(gè)add層Expression以及一個(gè)最大池化MaxPool2d層.








審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 運(yùn)算符
    +關(guān)注

    關(guān)注

    0

    文章

    171

    瀏覽量

    11051
  • float
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    7766
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    802

    瀏覽量

    13116

原文標(biāo)題:自制深度學(xué)習(xí)推理框架-第六課-構(gòu)建自己的計(jì)算圖

文章出處:【微信號(hào):GiantPandaCV,微信公眾號(hào):GiantPandaCV】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    如何利用PyTorch API構(gòu)建CNN?

      很多人對(duì)于卷積神經(jīng)網(wǎng)絡(luò)(CNN)并不了解,卷積神經(jīng)網(wǎng)絡(luò)是一種前饋神經(jīng)網(wǎng)絡(luò),它包括卷積計(jì)算并具有很深的結(jié)構(gòu),卷積神經(jīng)網(wǎng)絡(luò)是深度學(xué)習(xí)的代表性算法之。那么如何利用
    發(fā)表于 07-16 18:13

    TVM整體結(jié)構(gòu),TVM代碼的基本構(gòu)成

    TIR是更接近硬件的表示結(jié)構(gòu)。Relay中IR通過relay::function來(lái)描述,function描述了整個(gè)結(jié)構(gòu),是結(jié)構(gòu)的另外
    發(fā)表于 01-07 17:21

    一種基于MapReduce的結(jié)構(gòu)聚類算法

    (tril5)(m為圖中邊的條數(shù)),因此很難處理大規(guī)模的數(shù)據(jù)。為了解決SCAN算法的可擴(kuò)展性問題,提出了一種新穎的基于MapReduce的海量結(jié)構(gòu)聚類算法MRSCAN。具體地,提出
    發(fā)表于 12-19 11:05 ?0次下載
    <b class='flag-5'>一種</b>基于MapReduce的<b class='flag-5'>圖</b><b class='flag-5'>結(jié)構(gòu)</b>聚類算法

    教你用PyTorch快速準(zhǔn)確地建立神經(jīng)網(wǎng)絡(luò)

    動(dòng)態(tài)計(jì)算PyTorch被稱為“由運(yùn)行定義的”框架,這意味著計(jì)算結(jié)構(gòu)(神經(jīng)網(wǎng)絡(luò)體系
    的頭像 發(fā)表于 02-11 14:33 ?3243次閱讀

    基于PyTorch的深度學(xué)習(xí)入門教程之PyTorch的安裝和配置

    神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),并且運(yùn)用各種深度學(xué)習(xí)算法訓(xùn)練網(wǎng)絡(luò)參數(shù),進(jìn)而解決各種任務(wù)。 本文從PyTorch環(huán)境配置開始。PyTorch一種Python接口的深度學(xué)習(xí)框架,使用靈活,學(xué)習(xí)方便。還有其
    的頭像 發(fā)表于 02-16 15:15 ?2541次閱讀

    基于PyTorch的深度學(xué)習(xí)入門教程之PyTorch的自動(dòng)梯度計(jì)算

    計(jì)算 Part3:使用PyTorch構(gòu)建個(gè)神經(jīng)網(wǎng)絡(luò) Part4:訓(xùn)練個(gè)神經(jīng)網(wǎng)絡(luò)分類器 Part5:數(shù)據(jù)并行化 本文是關(guān)于Part2的內(nèi)容
    的頭像 發(fā)表于 02-16 15:26 ?1984次閱讀

    基于PyTorch的深度學(xué)習(xí)入門教程之使用PyTorch構(gòu)建個(gè)神經(jīng)網(wǎng)絡(luò)

    PyTorch的自動(dòng)梯度計(jì)算 Part3:使用PyTorch構(gòu)建個(gè)神經(jīng)網(wǎng)絡(luò) Part4:訓(xùn)練
    的頭像 發(fā)表于 02-15 09:40 ?2066次閱讀

    PyTorch教程5.3之前向傳播、反向傳播和計(jì)算

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程5.3之前向傳播、反向傳播和計(jì)算.pdf》資料免費(fèi)下載
    發(fā)表于 06-05 15:36 ?0次下載
    <b class='flag-5'>PyTorch</b>教程5.3之前向傳播、反向傳播和<b class='flag-5'>計(jì)算</b><b class='flag-5'>圖</b>

    pytorch如何構(gòu)建網(wǎng)絡(luò)模型

      利用 pytorch 來(lái)構(gòu)建網(wǎng)絡(luò)模型有很多種方法,以下簡(jiǎn)單列出其中的四?! 〖僭O(shè)構(gòu)建個(gè)網(wǎng)絡(luò)模型如下:  卷積層--》Relu 層--
    發(fā)表于 07-20 11:51 ?0次下載

    中科曙光打造一種全新的計(jì)算體系構(gòu)建與運(yùn)營(yíng)模式—“立體計(jì)算

    4月2日,中科曙光“立體計(jì)算湖南行”啟動(dòng)儀式在長(zhǎng)沙成功舉辦。面對(duì)“加快發(fā)展新質(zhì)生產(chǎn)力”的新要求,中科曙光提出“立體計(jì)算”新思路,旨在打造一種全新的計(jì)算體系
    的頭像 發(fā)表于 04-03 09:52 ?409次閱讀
    中科曙光打造<b class='flag-5'>一種</b>全新的<b class='flag-5'>計(jì)算</b>體系<b class='flag-5'>構(gòu)建</b>與運(yùn)營(yíng)模式—“立體<b class='flag-5'>計(jì)算</b>”

    使用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò)

    PyTorch個(gè)流行的深度學(xué)習(xí)框架,它以其簡(jiǎn)潔的API和強(qiáng)大的靈活性在學(xué)術(shù)界和工業(yè)界得到了廣泛應(yīng)用。在本文中,我們將深入探討如何使用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò),包括從基礎(chǔ)概念到高級(jí)
    的頭像 發(fā)表于 07-02 11:31 ?619次閱讀

    如何使用PyTorch建立網(wǎng)絡(luò)模型

    PyTorch個(gè)基于Python的開源機(jī)器學(xué)習(xí)庫(kù),因其易用性、靈活性和強(qiáng)大的動(dòng)態(tài)特性,在深度學(xué)習(xí)領(lǐng)域得到了廣泛應(yīng)用。本文將從PyTorch
    的頭像 發(fā)表于 07-02 14:08 ?341次閱讀

    PyTorch如何訓(xùn)練自己的數(shù)據(jù)集

    PyTorch個(gè)廣泛使用的深度學(xué)習(xí)框架,它以其靈活性、易用性和強(qiáng)大的動(dòng)態(tài)特性而聞名。在訓(xùn)練深度學(xué)習(xí)模型時(shí),數(shù)據(jù)集是不可或缺的組成部分。然而,很多時(shí)候,我們可能需要使用
    的頭像 發(fā)表于 07-02 14:09 ?1193次閱讀

    PyTorch的特性和使用方法

    使用Python重新寫了很多內(nèi)容,使其更加靈活易用。它不僅是個(gè)擁有自動(dòng)求導(dǎo)功能的深度神經(jīng)網(wǎng)絡(luò)框架,還可以看作是個(gè)加入了GPU支持的NumPy。PyTorch支持動(dòng)態(tài)
    的頭像 發(fā)表于 07-02 14:27 ?452次閱讀

    pytorch如何訓(xùn)練自己的數(shù)據(jù)

    本文將詳細(xì)介紹如何使用PyTorch框架來(lái)訓(xùn)練自己的數(shù)據(jù)。我們將從數(shù)據(jù)準(zhǔn)備、模型構(gòu)建、訓(xùn)練過程、評(píng)估和測(cè)試等方面進(jìn)行講解。 環(huán)境搭建 首先,我們需要安裝PyTorch??梢酝ㄟ^訪問
    的頭像 發(fā)表于 07-11 10:04 ?421次閱讀