next.js 13.4のblogのapp routerについて要約
以前まではpages routerという仕組みが、app routerという機構となり、さらにstableとなった。
本記事は、next.jsを昔ちょろっと触ったことのある程度の筆者の、メモの役割程度のものなので、より詳しい情報が知りたい人は原文を読んでほしい。
以下本文となります。
app routerではnext.jsの4つのprinciples:
- Zero setup. Use the filesystem as an API
- Only JavaScript. Everything is a function
- Automatic server rendering and code splitting
- Data fetching is up to the developer
に近づくための機能が提供される。
zero config
next.jsはページ全体の共通の設定などをpages/_app.jsとpages/_document.jsで設定していた。
_app.jsにはlayout定義やglobalな状態管理のためのコンポーネントを用いたラップなどを行う。RecoilRootなどもここに記述する。
_document.jsにはhtllタグやheadタグなどを記述する。
app routerではこの2つの設定ファイルを記述する必要がなくなった。
ではどのように変わったのか。
まず、layoutをfolderごとに定義できるようになった。app/があったとき、app/layout.jsをrootのlayoutとして定義すると、app/page.jsではそのレイアウトが適用される。rootのlayoutではhtmlタグなどを記述し、これは_document.jsの代わりとなる。
また、layoutはnestすることができ、app/dashboard/layout.jsを定義すれば、それはdashboard/以下のcomponent用のlayoutとなる。
only JavaScript. Everything is a function
今まではgetStaticPropsなどdata fetch用の関数をapp/fetch.jsのような外部ファイルに書き出し、componentの記述と分離していた。fetchしたデータはpropsバケツリレーでcomponentに渡していた。
また、getStaticPropasやgetServerSidePropsを明示的に書くことで、data fetchをどこで実行(例:クライアントかサーバーか)するかをnext.jsがよしなに最適化してくれていた。
しかしそれはnext.jsの都合であり、”just JavaScript”の原則に反している。
そこでapp routerでは、component内でのfetchの記述が可能となっている。これによりバケツリレーも減少し、記述は楽になる。
また、デフォルトでcomponentはReact Server Componentsのため、fetchはserver上で実行される。サーバーサイドでのfetchが主となることに付随するキャッシュ戦略などの変化については他の記事を参照されたい。(自分もそのレベルの解釈ができるレベルではない)
Data fetching is up to the developer
fetchがcomponent内で記述でき、かつserver上で実行されるため、data fetching is up to the developerの原則にもより近づく。
そもそもこの原則は、開発者がより柔軟にfetchを行えるのがいいよねということなので、どんなcomponentでもfetchができるこの機能はよりイケてるよねってことを言いたいんだと思う。(ここは自分でも理解があやふやなので主観です)
例えばreact-tweetのようなサードパーティーのcomponentを用いるときでも、server上でのfetchが保証される。
Automatic server rendering and code splitting
next.jsが出た当初、renderingやcode splittingの最適化はwebpackなどさまざまなエコシステテムを用いてプロが職人技を披露するといったことが一般的だった。そういった職人技のコストを減らすため、最適化をよしなに行ってくれるいくつかの機能を提供しており、route-basedなcode splittingはその一つである。これは名前の通りpages/ 以下のディレクトリがJS bundleとして分割され、初期表示を高速化する。(単一のドデカjsを読み込まなくて済む)
ただしディレクトリ単位だけでは最適化のプロたちは満足せず、component単位でもcode splittingを行えないかと考えられた。
もちろんnext.jsはそのための機能を提供していたが、next/dynamiからdynamicと呼ばれる関数を呼び出し、その関数に明示的にcomponentを渡してあげる必要があった。
app routerでは、そもそもreact server componetsをデフォルトで利用するためclientのためにjsをbundleすることを考えなくて良い。
またclientのcomponentはwebpack/Turbopackによって自動でsplitされる。
さらにapp routerはreact suspense (loading時などに、componentのハンドリングを担当してくれる)を統合しているので、`return isLoggedIn ? <Dashboard /> : <Landing />;`のようにconditionalに、loadingの状態をcode split付きで制御できる。
以上
vggのdiscussionが面白かった
初学者な猫
最近cnnを用いたdeep learningについて入門している猫です。
かなり浅くしか読めていませんが、vggの論文のsec 2.3 discussion を読んで、初学者なりに、おおなるほどと思ったことがあったのでメモしておきます。
以下に論文のリンクを貼っておきます。
https://arxiv.org/pdf/1409.1556.pdf
おもしろひ
vggの特徴として、vggが発表されるまで流行っていた構成に比べ、畳み込み層のフィルタを小さく(5×5, 7×7などから3×3に)、そしてネットワーク全体の層を深くしたことがあります
そして、今回猫が面白いなと思った箇所は以下の部分です
It is easy to see that a stack of two 3×3 conv. layers (without spatial pooling in between) has an effective receptive field of 5×5; three such layers have a 7 × 7 effective receptive field.
まあ書いてあることは、3×3のフィルタを2つ積むなら、5×5を1つ積めばよくね?同様に、3×3を3つ積むなら、7×7を1つ積めばよくね?
ということなのですが、ざっくりとした僕の理解では、以下のようなことだと認識しています
参考文献[1]によると、
ここでは、入力サイズを (H, W )、フィルターサイズを (F H, F W )、出力サイズを (OH, OW )、パディングを P 、ストライドを S とします。その場合、出力サイズは 次の式 (7.1) で計算できます。
式が画像ですみません(猫)
計算
今回、パディングは0,ストライドは1,入力画像はW:10, H10としましょう。まあ簡単のためチャネル数も1として、、、
式(7.1)により計算すると、まず3×3の場合は、(OH,OW) = (8,8)で1つ目の出力がなされ、そして2つ目で8×8が入力となり、最終的に(OH,OW) = (6,6)が得られる。
次に5×5の場合、(OH,OW) = (10-5+1,10-5+1) = (6,6)となる
以上の計算より出力サイズは一緒になって良い感じになるよねって話だと思います、サイズの観点からしかみていないので浅い理解ですが
ではなぜ3×3?
論文では、reruを入れられることと、重みについて触れてくれています
So what have we gained by using, for instance, a stack of three 3×3 conv. layers instead of a single 7×7 layer? First, we incorporate three non-linear rectification layers instead of a single one, which makes the decision function more discriminative. Second, we decrease the number of parameters: assuming that both the input and the output of a three-layer 3 × 3 convolution stack has C channels, the stack is parametrised by 3(32 C2)= 27C2 weights; at the same time, a single 7 × 7 conv. layer would require 72 C2 = 49C2 parameters, i.e. 81% more.
1つ目はReluを増やせるので、表現力を増すことができるということだと思います。
2つ目なのですが、畳み込み層の重みは(filter size) × 入力ch数 × 出力ch数であるので、上記のような式となります。
引用を見ると(1 - 49 ÷ 27) *100 %も多いらしいですねこ
なるほどなあ
初学者にはこういったdiscussionはとても勉強になりました
参考文献
[1] ゼロから作るDeep Learning (pythonで学ぶディープラーニングの理論と実装)
comet Ⅱで大文字小文字判定メモ猫
comet Ⅱ すごい
comet Ⅱはモデルアーキテクチャの一つで、一般性を失うことなく簡単化されている。つまり猫でもわかりやすい
今回はcomet Ⅱに対応するアセンブリ言語であるcasl Ⅱを用いて、入力装置から入力された文字が小文字だったら大文字に、大文字だったら小文字に変換し、出力装置に書き込む処理を実現したい(猫が)
かいてみる(猫が)
参考文献のp32のプログラムを参考に記述する
1 C_TRNS START 2 IN CA, CN 3 LD GR2, CA 4 LAD GR0, #0060 5 LAD GR1, #0020 6 CPA GR2, GR0 7 JPL StoL 8 ADDA GR2, GR1 9 JUMP WRITE 10 StoL SUBA GR2, GR1 11 WRITE ST GR2, CA 12 OUT CA, CN 13 RET 14 CA DS 256 15 CN DS 1 16 END
なんとなく理解する
IN, OUT
2行目と12行目で、それぞれ入出力装置からの入出力を行なっている。入力はキーボードなどから、出力はディスプレイなど、の解釈で良さそう?
3,4,5行目
3行目はレジスタ間ロード命令、4,5行目はロードアドレス命令。前者は入力領域CAをレジスタGR2へ転送していて、後者は#0060(文字定数'a'に対する文字コードよりも1だけ小さいデータ)と#0020(小文字データと大文字データの差)をGR0,GR1に格納している。
6~10行目
ここで比較、もし入力文字が#0060よりも小さければ、入力文字は大文字ということであるため、サインフラグがたち、JPLは実行されず、加算処理がなされ、小文字に変換される。
すごい
アセンブリはすごい
少し入門できました
参考文献
コンピュータアーキテクチャ 福本聡, 岩崎一彦 著
pythonでdfs
dfsの勉強がしたいネコ
dfsの勉強がしたいよお 今回は教材として、この方の記事を参考にさせていただきます。
DFS (深さ優先探索) 超入門! 〜 グラフ・アルゴリズムの世界への入口 〜【後編】 - Qiita
解く問題はこれ
ほぼ記事通りに、pythonで書いていきます
def dfs_grid(h, w): # true:巡回済み seen[h][w] = True for direction in range(4): # new_h,new_w nh = h + dx[direction] nw = w + dy[direction] #進めなかったり巡回済みだったりしたらスルー if (nh < 0 or nh >=H or nw < 0 or nw >=W): continue if field[nh][nw] == '#': continue if seen[nh][nw]: continue dfs_grid(nh, nw) H,W=map(int, input().split()) field=[list(list(input())) for i in range(H)] # 右、上、左、下 dx = [1, 0, -1, 0] dy = [0, 1, 0, -1] seen = [[False for i in range(W)] for j in range(H)] for h in range(H): for w in range(W): if field[h][w] == 's': sh, sw = h, w if field[h][w] == 'g': gh, gw = h, w dfs_grid(sh,sw) if(seen[gh][gw]): print('Yes') else: print('No')
記事が分かり易すぎてすぐにdfsを実装できました、提出するぞ ......
reが出てしまいます
んーーー、reということはindexか、それとももっと何か他のことか、、 とネコのように悩んでいたら、神記事を見つけましたので、参考にさせていただきました
Python 競技プログラミング高速化tips (PythonでAtcoderをやる際に個人的に気を付けてること)
だそうです。なるほど
以下のコードを記述すると、reが消えました!ネコ
pythonではあまり再帰は使わない方が良いかもしれません、、
import sys sys.setrecursionlimit(4100000)
参考文献
DFS (深さ優先探索) 超入門! 〜 グラフ・アルゴリズムの世界への入口 〜【後編】 - Qiita (drken - Qiita)
Python 競技プログラミング高速化tips (PythonでAtcoderをやる際に個人的に気を付けてること) (https://juppy.hatenablog.com/about)
scikit-learnでprecision,recall,f値 [ネコ]
import
import numpy as np import os
やっていく
mnistを使います
まずはmnistをfetch
from sklearn.datasets import fetch_mldata mnist = fetch_mldata('MNIST original')
mnist.data.shape
# (70000, 784)
特徴量は28×28で784
70000個インスタンスがあるぽい、70000万匹のネコ.......
mnist.target.shape
# (70000,)
訓練データとテストデータを分けます
60000個が訓練データに、、、60000のネコ
X, y = mnist["data"], mnist["target"] X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]
訓練データをシャッフルします。交差検証の時に検証されない数字があると困るからです。
np.random.seed(42) shuffle_idx = np.random.permutation(60000) X_train, y_train = X_train[shuffle_idx], y_train[shuffle_idx]
今回は簡単のため5を判定してみます、これならネコでもわかる!!
5のデータだけtrueに、それ以外はfalseに
この書き方はスッキリしてて良いですね!! スッキリしたねこ,,,,,,,,
y_train_5 = (y_train == 5) y_test_5 = (y_test == 5)
sgdの分類機を試します、学習させましょう
sgdについては 確率的勾配降下法とは何か、をPythonで動かして解説する - Qiita こちらの記事がわかりやすかったです!天才だ、、
from sklearn.linear_model import SGDClassifier sgd_clf = SGDClassifier(max_iter=5, tol=-np.infty, random_state=42) sgd_clf.fit(X_train, y_train_5)
交差検証をします、今回は3フォールドのK分割交差検証でモデルを評価します。この時、cross_val_predict()を使用すると精度ではなく予測結果そのものを返してくれます。
from sklearn.model_selection import cross_val_predict y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3) y_train_pred # array([False, False, False, ..., False, False, False])
precision, recall, f値を求めましょう!!!終わった、、これでアイス食べれる、、、、
from sklearn.metrics import precision_score, recall_score, f1_score print('precision:', precision_score(y_train_5, y_train_pred)) print('recall:', recall_score(y_train_5, y_train_pred)) print('f1:', f1_score(y_train_5, y_train_pred)) # precision: 0.7687135020350381 # recall: 0.801328168234643 # f1: 0.7846820809248555
参考文献: scikit-learnとTensorFlowによる実践機械学習 (オライリー・ジャパン, Aurelien geron 著, 下田倫大 監訳, 長尾高弘 訳)