[{"data":1,"prerenderedAt":904},["ShallowReactive",2],{"content-\u002Fcontents\u002Fpytorch-more-adv":3,"surroundPost-\u002Fcontents\u002Fpytorch-more-adv":895},{"id":4,"title":5,"body":6,"createdAt":883,"description":884,"draft":885,"extension":886,"meta":887,"navigation":153,"path":888,"seo":889,"stem":890,"tags":891,"thumbnail":893,"updatedAt":883,"__hash__":894},"contents\u002Fcontents\u002Fpytorch-more-adv.md","PyTorchの勾配更新方法の解説",{"type":7,"value":8,"toc":876},"minimark",[9,13,25,28,33,44,47,76,83,89,92,255,265,281,290,297,301,304,307,360,363,366,369,413,420,423,426,429,434,437,441,448,451,459,462,465,468,475,478,520,523,699,702,705,728,731,860,863,866,869,872],[10,11,12],"p",{},"今回も PyTorch に関する記事です。",[10,14,15,16,20,21,24],{},"この記事では、",[17,18,19],"code",{},"requires_grad","、",[17,22,23],{},"zero_grad","などについて説明します。",[10,26,27],{},"私自身も勉強中ということもあり間違い等あるかもしれません。その際は Twitter などで教えてください。",[29,30,32],"h2",{"id":31},"requires_grad-とは","requires_grad とは",[10,34,35,40,41,43],{},[36,37,39],"a",{"href":38},"pytorch-beginer","【学び直し】Pytorch の基本と MLP で MNIST の分類・可視化の実装まで","で紹介したように、",[17,42,19],{},"は自動微分を行うためのフラグです。",[10,45,46],{},"単純に tensor を定義した場合はデフォルトで False になっています。",[48,49,54],"pre",{"className":50,"code":51,"language":52,"meta":53,"style":53},"language-py shiki shiki-themes github-dark","x = torch.ones([3, 32, 32])\nx.requires_grad\n# >>> False\n","py","",[17,55,56,64,70],{"__ignoreMap":53},[57,58,61],"span",{"class":59,"line":60},"line",1,[57,62,63],{},"x = torch.ones([3, 32, 32])\n",[57,65,67],{"class":59,"line":66},2,[57,68,69],{},"x.requires_grad\n",[57,71,73],{"class":59,"line":72},3,[57,74,75],{},"# >>> False\n",[10,77,78,79,82],{},"一方で、ネットワークを定義した場合のパラメータはデフォルトで",[17,80,81],{},"requires_grad=True","です。",[10,84,85,86,88],{},"意外とこれを知らずにわざわざ学習時に",[17,87,81],{},"を設定していることがあります。",[10,90,91],{},"実際に定義したネットワークで確かめてみました。",[48,93,95],{"className":50,"code":94,"language":52,"meta":53,"style":53},"# Networkを定義\nclass MLPNet (nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.fc1 = nn.Linear(1 * 28 * 28, 512)\n        self.fc2 =nn.Linear(512, 512)\n        self.fc3 = nn.Linear(512, 10)\n        self.dropout1=nn.Dropout2d(0.2)\n        self.dropout2=nn.Dropout2d(0.2)\n\n    def forward(self, x):\n        x = F.relu(self.fc1(x))\n        x = self.dropout1(x)\n        x = F.relu(self.fc2(x))\n        x = self.dropout2(x)\n        return F.relu(self.fc3(x))\n\nnet = MLPNet().to(device)\nfor name, p in net.named_parameters():\n    print(name, p.requires_grad)\n\n# >>> fc1.weight True\n# >>> fc1.bias True\n# >>> fc2.weight True\n# >>> fc2.bias True\n# >>> fc3.weight True\n# >>> fc3.bias True\n",[17,96,97,102,107,112,118,124,130,136,142,148,155,161,167,173,179,185,191,196,202,208,214,219,225,231,237,243,249],{"__ignoreMap":53},[57,98,99],{"class":59,"line":60},[57,100,101],{},"# Networkを定義\n",[57,103,104],{"class":59,"line":66},[57,105,106],{},"class MLPNet (nn.Module):\n",[57,108,109],{"class":59,"line":72},[57,110,111],{},"    def __init__(self):\n",[57,113,115],{"class":59,"line":114},4,[57,116,117],{},"        super().__init__()\n",[57,119,121],{"class":59,"line":120},5,[57,122,123],{},"        self.fc1 = nn.Linear(1 * 28 * 28, 512)\n",[57,125,127],{"class":59,"line":126},6,[57,128,129],{},"        self.fc2 =nn.Linear(512, 512)\n",[57,131,133],{"class":59,"line":132},7,[57,134,135],{},"        self.fc3 = nn.Linear(512, 10)\n",[57,137,139],{"class":59,"line":138},8,[57,140,141],{},"        self.dropout1=nn.Dropout2d(0.2)\n",[57,143,145],{"class":59,"line":144},9,[57,146,147],{},"        self.dropout2=nn.Dropout2d(0.2)\n",[57,149,151],{"class":59,"line":150},10,[57,152,154],{"emptyLinePlaceholder":153},true,"\n",[57,156,158],{"class":59,"line":157},11,[57,159,160],{},"    def forward(self, x):\n",[57,162,164],{"class":59,"line":163},12,[57,165,166],{},"        x = F.relu(self.fc1(x))\n",[57,168,170],{"class":59,"line":169},13,[57,171,172],{},"        x = self.dropout1(x)\n",[57,174,176],{"class":59,"line":175},14,[57,177,178],{},"        x = F.relu(self.fc2(x))\n",[57,180,182],{"class":59,"line":181},15,[57,183,184],{},"        x = self.dropout2(x)\n",[57,186,188],{"class":59,"line":187},16,[57,189,190],{},"        return F.relu(self.fc3(x))\n",[57,192,194],{"class":59,"line":193},17,[57,195,154],{"emptyLinePlaceholder":153},[57,197,199],{"class":59,"line":198},18,[57,200,201],{},"net = MLPNet().to(device)\n",[57,203,205],{"class":59,"line":204},19,[57,206,207],{},"for name, p in net.named_parameters():\n",[57,209,211],{"class":59,"line":210},20,[57,212,213],{},"    print(name, p.requires_grad)\n",[57,215,217],{"class":59,"line":216},21,[57,218,154],{"emptyLinePlaceholder":153},[57,220,222],{"class":59,"line":221},22,[57,223,224],{},"# >>> fc1.weight True\n",[57,226,228],{"class":59,"line":227},23,[57,229,230],{},"# >>> fc1.bias True\n",[57,232,234],{"class":59,"line":233},24,[57,235,236],{},"# >>> fc2.weight True\n",[57,238,240],{"class":59,"line":239},25,[57,241,242],{},"# >>> fc2.bias True\n",[57,244,246],{"class":59,"line":245},26,[57,247,248],{},"# >>> fc3.weight True\n",[57,250,252],{"class":59,"line":251},27,[57,253,254],{},"# >>> fc3.bias True\n",[10,256,257,258,260,261,264],{},"このように",[17,259,81],{},"になってます。\nちなみに",[17,262,263],{},"named_parameters()","とすることでレイヤーの名前とパラメータを参照できます。",[10,266,267,273,274,277,278,280],{},[36,268,272],{"href":269,"rel":270},"https:\u002F\u002Fpytorch.org\u002Fdocs\u002Fstable\u002Fnn.html#parameters",[271],"nofollow","ドキュメント","によるとネットワークで各層を定義した際に用いられる",[17,275,276],{},"nn.Prameter","がデフォルトで",[17,279,81],{},"なので上記の結果になります。",[10,282,283,285,286,289],{},[17,284,81],{},"が求められるのは、",[17,287,288],{},"backward","で勾配を計算したいところです。",[10,291,292,293,296],{},"逆に、勾配の更新を行わないところは明示的に",[17,294,295],{},"requires_grad=False","とする必要があります。",[29,298,300],{"id":299},"optim-について","optim について",[10,302,303],{},"optim は pytorch で学習を行う際に用いる最適化関数です。",[10,305,306],{},"今回も簡単な式で挙動を確認します。",[48,308,310],{"className":50,"code":309,"language":52,"meta":53,"style":53},"import torch\nimport torch.optim as optim\n\nx = torch.tensor(3.0, requires_grad=True)\nw = torch.tensor(2.0, requires_grad=True)\nb = torch.tensor(1.0, requires_grad=True)\nyy = torch.tensor(5.0, requires_grad=True)\ny = w * x + b\n\nopt = optim.SGD([w,b], lr=0.01, momentum=0.9)\n",[17,311,312,317,322,326,331,336,341,346,351,355],{"__ignoreMap":53},[57,313,314],{"class":59,"line":60},[57,315,316],{},"import torch\n",[57,318,319],{"class":59,"line":66},[57,320,321],{},"import torch.optim as optim\n",[57,323,324],{"class":59,"line":72},[57,325,154],{"emptyLinePlaceholder":153},[57,327,328],{"class":59,"line":114},[57,329,330],{},"x = torch.tensor(3.0, requires_grad=True)\n",[57,332,333],{"class":59,"line":120},[57,334,335],{},"w = torch.tensor(2.0, requires_grad=True)\n",[57,337,338],{"class":59,"line":126},[57,339,340],{},"b = torch.tensor(1.0, requires_grad=True)\n",[57,342,343],{"class":59,"line":132},[57,344,345],{},"yy = torch.tensor(5.0, requires_grad=True)\n",[57,347,348],{"class":59,"line":138},[57,349,350],{},"y = w * x + b\n",[57,352,353],{"class":59,"line":144},[57,354,154],{"emptyLinePlaceholder":153},[57,356,357],{"class":59,"line":150},[57,358,359],{},"opt = optim.SGD([w,b], lr=0.01, momentum=0.9)\n",[10,361,362],{},"optim の引数には学習したいパラメータと学習率などを渡します。",[10,364,365],{},"ここで、学習したいパラメータは iteration の形である必要があるためカッコでくくってます。",[10,367,368],{},"実際に optim で最適化してみます。",[48,370,372],{"className":50,"code":371,"language":52,"meta":53,"style":53},"criterion = nn.MSELoss()\n\nfor epoch in range(3):\n    opt.zero_grad()\n    y = w * x + b\n    loss = criterion(y, yy)\n    loss.backward()\n    opt.step()\n",[17,373,374,379,383,388,393,398,403,408],{"__ignoreMap":53},[57,375,376],{"class":59,"line":60},[57,377,378],{},"criterion = nn.MSELoss()\n",[57,380,381],{"class":59,"line":66},[57,382,154],{"emptyLinePlaceholder":153},[57,384,385],{"class":59,"line":72},[57,386,387],{},"for epoch in range(3):\n",[57,389,390],{"class":59,"line":114},[57,391,392],{},"    opt.zero_grad()\n",[57,394,395],{"class":59,"line":120},[57,396,397],{},"    y = w * x + b\n",[57,399,400],{"class":59,"line":126},[57,401,402],{},"    loss = criterion(y, yy)\n",[57,404,405],{"class":59,"line":132},[57,406,407],{},"    loss.backward()\n",[57,409,410],{"class":59,"line":138},[57,411,412],{},"    opt.step()\n",[10,414,415,416,419],{},"まず、",[17,417,418],{},"opt.zero_grad()","で勾配をゼロにリセットします。",[10,421,422],{},"これをしないと勾配が蓄積されたままになってしまうので、正しい方向に更新されなくなります。",[10,424,425],{},"数式でかくと、パラメータ$w$を更新する際は以下のようになります（SGD の場合）。",[10,427,428],{},"$$\nw ← w - lr \\frac{\\partial L}{\\partial w}\n$$",[10,430,431,433],{},[17,432,418],{},"を使わないと、偏微分部分が前の勾配との和になってしまうので、正しい方向に更新されません。",[10,435,436],{},"簡単に手計算で確かめられるので、一度計算してみると何が行われているかイメージできます。",[438,439,440],"h3",{"id":440},"パラメータの更新について",[10,442,443,444,82],{},"PyTorch を使い始めてまず混乱するのが、",[445,446,447],"strong",{},"なぜ optim の操作で model の値が更新されるのか",[10,449,450],{},"結論からいうと、model パラメータのアドレスを optim の初期化のときに渡しているからです。",[48,452,453],{"className":50,"code":359,"language":52,"meta":53,"style":53},[17,454,455],{"__ignoreMap":53},[57,456,457],{"class":59,"line":60},[57,458,359],{},[10,460,461],{},"ここまでは大丈夫だと思います。",[10,463,464],{},"気をつけないといけないのが、学習の途中でパラメータを optim 以外の方法で更新する場合です。",[10,466,467],{},"例えば、GAN で重みの移動平均を計算する場合など。",[10,469,470,471,474],{},"そういう時は",[17,472,473],{},".data","で値を更新します。",[10,476,477],{},"model は先ほどの MLP だとして、まずは普通に値を更新します。",[48,479,481],{"className":50,"code":480,"language":52,"meta":53,"style":53},"net = MLPNet().to(device)\n\n# 最適化方法\noptimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)\n\nnet.fc1.weight = nn.Parameter(torch.ones([512, 784]))\nprint(net.fc1.weight)\nprint(optimizer.param_groups[0]['params'][0])\n",[17,482,483,487,491,496,501,505,510,515],{"__ignoreMap":53},[57,484,485],{"class":59,"line":60},[57,486,201],{},[57,488,489],{"class":59,"line":66},[57,490,154],{"emptyLinePlaceholder":153},[57,492,493],{"class":59,"line":72},[57,494,495],{},"# 最適化方法\n",[57,497,498],{"class":59,"line":114},[57,499,500],{},"optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)\n",[57,502,503],{"class":59,"line":120},[57,504,154],{"emptyLinePlaceholder":153},[57,506,507],{"class":59,"line":126},[57,508,509],{},"net.fc1.weight = nn.Parameter(torch.ones([512, 784]))\n",[57,511,512],{"class":59,"line":132},[57,513,514],{},"print(net.fc1.weight)\n",[57,516,517],{"class":59,"line":138},[57,518,519],{},"print(optimizer.param_groups[0]['params'][0])\n",[10,521,522],{},"この時の出力は以下のようになります。",[48,524,528],{"className":525,"code":526,"language":527,"meta":53,"style":53},"language-bash shiki shiki-themes github-dark","Parameter containing:\ntensor([[1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        ...,\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.]], requires_grad=True)\nParameter containing:\ntensor([[ 0.0323, -0.0328, -0.0338,  ..., -0.0061, -0.0316,  0.0097],\n        [-0.0309, -0.0281,  0.0229,  ...,  0.0164, -0.0236,  0.0347],\n        [-0.0184, -0.0026,  0.0323,  ..., -0.0353, -0.0310,  0.0208],\n        ...,\n        [ 0.0015,  0.0148,  0.0143,  ..., -0.0112, -0.0215,  0.0123],\n        [ 0.0332, -0.0148,  0.0235,  ..., -0.0001, -0.0148, -0.0104],\n        [ 0.0044, -0.0282, -0.0292,  ..., -0.0311, -0.0068,  0.0349]],\n       device='cuda:0', requires_grad=True)\n","bash",[17,529,530,540,560,569,575,583,589,595,610,616,641,648,655,661,668,675,680],{"__ignoreMap":53},[57,531,532,536],{"class":59,"line":60},[57,533,535],{"class":534},"svObZ","Parameter",[57,537,539],{"class":538},"sU2Wk"," containing:\n",[57,541,542,545,548,550,553,555,557],{"class":59,"line":66},[57,543,544],{"class":534},"tensor([[1.,",[57,546,547],{"class":538}," 1.,",[57,549,547],{"class":538},[57,551,552],{"class":538},"  ...,",[57,554,547],{"class":538},[57,556,547],{"class":538},[57,558,559],{"class":538}," 1.],\n",[57,561,562,566],{"class":59,"line":72},[57,563,565],{"class":564},"s95oV","        [1., 1., 1.,  ..., 1., 1., 1.]",[57,567,568],{"class":534},",\n",[57,570,571,573],{"class":59,"line":114},[57,572,565],{"class":564},[57,574,568],{"class":534},[57,576,577,581],{"class":59,"line":120},[57,578,580],{"class":579},"sDLfK","        ...",[57,582,568],{"class":538},[57,584,585,587],{"class":59,"line":126},[57,586,565],{"class":564},[57,588,568],{"class":534},[57,590,591,593],{"class":59,"line":132},[57,592,565],{"class":564},[57,594,568],{"class":534},[57,596,597,600,604,607],{"class":59,"line":138},[57,598,599],{"class":564},"        [1., 1., 1.,  ..., 1., 1., 1.]], requires_grad",[57,601,603],{"class":602},"snl16","=",[57,605,606],{"class":538},"True",[57,608,609],{"class":564},")\n",[57,611,612,614],{"class":59,"line":144},[57,613,535],{"class":534},[57,615,539],{"class":538},[57,617,618,621,624,627,630,632,635,638],{"class":59,"line":150},[57,619,620],{"class":534},"tensor([[",[57,622,623],{"class":538}," 0.0323,",[57,625,626],{"class":579}," -0.0328,",[57,628,629],{"class":579}," -0.0338,",[57,631,552],{"class":538},[57,633,634],{"class":579}," -0.0061,",[57,636,637],{"class":579}," -0.0316,",[57,639,640],{"class":538},"  0.0097],\n",[57,642,643,646],{"class":59,"line":157},[57,644,645],{"class":564},"        [-0.0309, -0.0281,  0.0229,  ...,  0.0164, -0.0236,  0.0347]",[57,647,568],{"class":534},[57,649,650,653],{"class":59,"line":163},[57,651,652],{"class":564},"        [-0.0184, -0.0026,  0.0323,  ..., -0.0353, -0.0310,  0.0208]",[57,654,568],{"class":534},[57,656,657,659],{"class":59,"line":169},[57,658,580],{"class":579},[57,660,568],{"class":538},[57,662,663,666],{"class":59,"line":175},[57,664,665],{"class":564},"        [ 0.0015,  0.0148,  0.0143,  ..., -0.0112, -0.0215,  0.0123]",[57,667,568],{"class":534},[57,669,670,673],{"class":59,"line":181},[57,671,672],{"class":564},"        [ 0.0332, -0.0148,  0.0235,  ..., -0.0001, -0.0148, -0.0104]",[57,674,568],{"class":534},[57,676,677],{"class":59,"line":187},[57,678,679],{"class":564},"        [ 0.0044, -0.0282, -0.0292,  ..., -0.0311, -0.0068,  0.0349]],\n",[57,681,682,685,687,690,693,695,697],{"class":59,"line":193},[57,683,684],{"class":564},"       device",[57,686,603],{"class":602},[57,688,689],{"class":538},"'cuda:0',",[57,691,692],{"class":564}," requires_grad",[57,694,603],{"class":602},[57,696,606],{"class":538},[57,698,609],{"class":564},[10,700,701],{},"このように optimizer の方の値は変わっていないです。",[10,703,704],{},"なので、optimizer 以外で重みを更新する場合は以下のようにします。",[48,706,708],{"className":50,"code":707,"language":52,"meta":53,"style":53},"# .dataで更新する\nnet.fc1.weight.data = nn.Parameter(torch.ones([512, 784]))\nprint(net.fc1.weight)\nprint(optimizer.param_groups[0]['params'][0])\n",[17,709,710,715,720,724],{"__ignoreMap":53},[57,711,712],{"class":59,"line":60},[57,713,714],{},"# .dataで更新する\n",[57,716,717],{"class":59,"line":66},[57,718,719],{},"net.fc1.weight.data = nn.Parameter(torch.ones([512, 784]))\n",[57,721,722],{"class":59,"line":72},[57,723,514],{},[57,725,726],{"class":59,"line":114},[57,727,519],{},[10,729,730],{},"こうすると optimizer の方の値も書き換わります。",[48,732,734],{"className":525,"code":733,"language":527,"meta":53,"style":53},"Parameter containing:\ntensor([[1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        ...,\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.]], requires_grad=True)\nParameter containing:\ntensor([[1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        ...,\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.],\n        [1., 1., 1.,  ..., 1., 1., 1.]], requires_grad=True)\n",[17,735,736,742,758,764,770,776,782,788,798,804,820,826,832,838,844,850],{"__ignoreMap":53},[57,737,738,740],{"class":59,"line":60},[57,739,535],{"class":534},[57,741,539],{"class":538},[57,743,744,746,748,750,752,754,756],{"class":59,"line":66},[57,745,544],{"class":534},[57,747,547],{"class":538},[57,749,547],{"class":538},[57,751,552],{"class":538},[57,753,547],{"class":538},[57,755,547],{"class":538},[57,757,559],{"class":538},[57,759,760,762],{"class":59,"line":72},[57,761,565],{"class":564},[57,763,568],{"class":534},[57,765,766,768],{"class":59,"line":114},[57,767,565],{"class":564},[57,769,568],{"class":534},[57,771,772,774],{"class":59,"line":120},[57,773,580],{"class":579},[57,775,568],{"class":538},[57,777,778,780],{"class":59,"line":126},[57,779,565],{"class":564},[57,781,568],{"class":534},[57,783,784,786],{"class":59,"line":132},[57,785,565],{"class":564},[57,787,568],{"class":534},[57,789,790,792,794,796],{"class":59,"line":138},[57,791,599],{"class":564},[57,793,603],{"class":602},[57,795,606],{"class":538},[57,797,609],{"class":564},[57,799,800,802],{"class":59,"line":144},[57,801,535],{"class":534},[57,803,539],{"class":538},[57,805,806,808,810,812,814,816,818],{"class":59,"line":150},[57,807,544],{"class":534},[57,809,547],{"class":538},[57,811,547],{"class":538},[57,813,552],{"class":538},[57,815,547],{"class":538},[57,817,547],{"class":538},[57,819,559],{"class":538},[57,821,822,824],{"class":59,"line":157},[57,823,565],{"class":564},[57,825,568],{"class":534},[57,827,828,830],{"class":59,"line":163},[57,829,565],{"class":564},[57,831,568],{"class":534},[57,833,834,836],{"class":59,"line":169},[57,835,580],{"class":579},[57,837,568],{"class":538},[57,839,840,842],{"class":59,"line":175},[57,841,565],{"class":564},[57,843,568],{"class":534},[57,845,846,848],{"class":59,"line":181},[57,847,565],{"class":564},[57,849,568],{"class":534},[57,851,852,854,856,858],{"class":59,"line":187},[57,853,599],{"class":564},[57,855,603],{"class":602},[57,857,606],{"class":538},[57,859,609],{"class":564},[29,861,862],{"id":862},"まとめ",[10,864,865],{},"PyTorch は便利で、なんとなく書いてもできてしまいます。",[10,867,868],{},"しかし、ちょっと発展的な内容を実装しようと思うと、勾配がどのように更新されるかなどを知らないと実装できないです。",[10,870,871],{},"今回実際に、細かく処理の経過を出力したりすることでだいぶ理解が進みました。",[873,874,875],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}",{"title":53,"searchDepth":66,"depth":66,"links":877},[878,879,882],{"id":31,"depth":66,"text":32},{"id":299,"depth":66,"text":300,"children":880},[881],{"id":440,"depth":72,"text":440},{"id":862,"depth":66,"text":862},"2020-07-07","requires_gradやzero_gradなど何気なく使っているPyTorchのあれこれを調べました。",false,"md",{},"\u002Fcontents\u002Fpytorch-more-adv",{"title":5,"description":884},"contents\u002Fpytorch-more-adv",[892],"PyTorch","\u002Fimg\u002Ftwitter-card.png","HhNuuWFN9zm5HxZyvJ3t78ING74qXPt5I2ceLhUDBfM",[896,900],{"title":897,"path":898,"stem":899,"children":-1},"【学び直し】Pytorchの基本とMLPでMNISTの分類・可視化の実装まで","\u002Fcontents\u002Fpytorch-beginer","contents\u002Fpytorch-beginer",{"title":901,"path":902,"stem":903,"children":-1},"Recursive Agent Harnesses","\u002Fcontents\u002Frecursive-agent-harnesses","contents\u002Frecursive-agent-harnesses",1785899327564]