普通列車を乗り継いで東日本を半周した話(2024/04)
はじめに
この記事は、筆者が2024年4月に青春18きっぷを利用して実行した甲府見物、およびリゾートしらかみへの乗車を目的とした新潟・酒田経由の東日本半周の記憶を文章化したものである。
過去の一人旅
私は普段作曲やゲームなどインドアな趣味を楽しむ人間で、休日は基本的に屋内で過ごす。しかし、たまには旅行したくなることもある。
10年前、当時仙台に住んでいた私は伊勢参りを企図し、その手段として最も安価に移動できる青春18きっぷを選択した。この時分は鉄道の知識をほとんど持っていなかったが、普通列車の乗り継ぎ方を分単位で考えたり、観光先を取捨選択したりするうちに楽しみが増幅していったのを覚えている。
最終的に、1日目は朝7時に仙台を発ち22時ごろに名古屋へ到着、2日目は伊勢神宮で観光、3日目に新幹線で帰宅という旅程になった。移ろいゆく景色を追いつつ10時間以上を列車で過ごした1日目の旅情は、私に新たな価値観をもたらした。2日目に訪れた伊勢神宮はこの半年前に二十年に一度の式年遷宮を終えたばかりで、新宮がとても美しかった。帰宅後も18きっぷの余った枠で隣県の山寺や中尊寺金色堂へ赴くなどし、私は鉄道を使ったひとつの旅の方法を覚えた。
今回の旅の動機
2月、私は偶然この動画を視聴した。
この動画に映っているのは秋田~青森間を走る観光列車「リゾートしらかみ」から望む日本海の絶景である。調べたところ列車が走るのは白神山地や岩木山を回り込むようにして日本海スレスレを通る1936年全通の五能線で、ここをJR東日本が観光スポットとして売り出していることを知った。

単純にいい景色だなと思ってその時は終わったが、後日「最近空いてて心配」といった旨のコメントが流れるのを目にした。興味のあるうちに行っておかないと後悔する気がしたのが決め手になり、リゾートしらかみへ乗りに行くことを決心した。
リゾートしらかみは「のってたのしい列車(観光列車)」のひとつで、みどりの窓口でだけでなく、えきねっとや自動券売機から同名のメニューを選択すれば簡単に予約できる。また私が乗車した4月7日(日)は実際にかなり空いていたが、時期によってはすぐ席が埋まるほどの人気があるようだ。(本記事を執筆中の12月5日(木)に、翌年1月4日(土)のリゾートしらかみ1号の予約率が既に7割あることを確認)
どのような旅がしたいのか?
次に、五能線へどのように行くかを決める必要があった。すぐに浮かんできたのは新幹線で秋田や青森まで行き、リゾートしらかみに乗り換えるルートだった。時期を選んで「おトクなきっぷ」を買えば比較的安く1泊2日の旅程を組めそうではある。しかしちょうど仕事に忙殺されていて乗り越えた先のご褒美が欲しく、リゾートしらかみをそれに当てはめようとする思考が支配的になった。
結果的に、ちょうど販売中だった青春18きっぷを行使して普通列車を乗り継ぐスタイルに落ち着いた。五能線へ行くだけでもたいへんな時間が掛かるが、その代わり2つのメリットがあった。一つは五能線へ至るまでの地域に足を運ぶ理由が出来ること、もう一つは青春18きっぷと指定席券(840円)だけでリゾートしらかみに乗車できることである。
※五能線が2日間乗り放題になるフリーパスが3,880円で販売されており、広域フリーパスの販売期間外に楽しみたい場合はそちらを購入するとお得に回れると思う。
最後にルートを検討した。まずは新潟や山形を経由する"西回り"ルート、宮城や岩手を経由する"東回り"ルートのどちらにするか考えたが、今回は完全に未踏だった新潟へ行っておきたいため西回りルートを選択した。路線については東京から長岡へ至る高崎線~上越線、および新潟県内から秋田へ伸びる羽越本線がすぐ確定したものの、新潟県内の路線が入り組んでいるためそこそこ悩まされた。そんなこんなで編み出されたのが以下の行程である。
- 1日目前半:7:04池袋発→高崎→水上→長岡→14:56新潟着
- 1日目後半:15:50新潟発→村上→19:30酒田着
- 2日目前半:7:56酒田発→秋田→【リゾートしらかみ】→15:50弘前着
- 2日目後半:16:15弘前発→青森→八戸→19:34本八戸着
- 3日目前半:8:45本八戸発→八戸→(新幹線)→9:41盛岡着
- 3日目後半:11:04盛岡発→一関→小牛田→仙台→白石→福島→郡山→新白河→黒磯→宇都宮→21:43上野着
2泊3日で収めるため3日目後半がなかなかキツい行程になったが、出来てしまうので決行することにした。
0日目:思い付きの甲府見物
4月2日、私は3月に休日出勤した分の代休を取り自宅でのんびりしていた。何となく週末に使う予定の青春18きっぷを見ていた時、ふと2日分の枠を残していることが気に掛かった。今春の18きっぷ利用期限は4月10日だったため、旅の後は消費チャンスが残っていないのであった。然らば、代休を取った今日こそ消費せねば。そう思い立ち、急遽昼過ぎに部屋を飛び出した。
目的地はそこそこ遠く、かつ滞在時間の取れる行ったことのない場所ということで甲府に決めた。そして新宿駅から中央線中央特快で高尾まで行き、さらに松本行きの普通列車に乗り継いだ。列車は山々を削って流れる桂川(相模川)を遡るように進み行き、やがて甲府盆地に差し掛かると、勝沼ぶどう郷駅停車中には甚六桜公園に山と咲く桜が車窓を彩った。

甲府駅には薄暮の17時40分過ぎに到着した。帰りは20時8分の上り列車と決め、取り敢えず駅周辺を散策しながら夕食をどこで頂くか考えた。最終的に駅前の有名な小作に入店し、豚肉ほうとうとビールを注文した。初めてほうとうを食べたが、太く長い麺は食べ応えがあり、味噌ベースの汁に入ったかぼちゃが美味しかった。

食事を終えるとまだ時間があったので、甲府城跡地の舞鶴城公園へ足を運んだ。入り口の内松陰門から銅門跡を通って本丸へ入り、さらに天守台へ上がると電灯で縁取られた甲府の街を見下ろすことが出来た。天守台の反対側には、大水害に遭った山梨へ明治天皇が施した支援に対し、感謝を表明するために建てられたという謝恩碑があった。本丸で遊んでいた子供がこの謝恩碑のことをミサイル呼ばわりしていたことが妙に頭にこびりついている。復元された大きな鉄門をくぐり帰路に就こうとすると、天守曲輪に植えられた桜並木が花を咲かせていたので、しばらく足を止めて眺めた。公園出口の鍛冶曲輪門を出たところで時計を見ると帰りの列車の発車時刻まで10分を切っており、私は慌てて甲府駅へダッシュしたのだった。


1日目:前編(池袋~新潟)
4月6日早朝7時4分、私は湘南新宿ラインの列車に乗り、計画通り池袋から高崎へ出発した。列車の外ではなるべく歩きたいので、荷物を2日分の着替えや飲料を入れたリュックサック(+貴重品)だけにしていた。
8時50分ごろ高崎駅に着き、駅ビルのパン屋で朝食を取ると、いよいよ本格的な移動が始まる。改札内の発車標には今まで縁のなかった路線名が連なり、これだけでも私にとっては楽しみな光景であった。

10時24分発の列車で春の日差しを浴びる上越線を下っていくと、群馬県北の沼田市を過ぎた辺りから左右に緑と土色の山が迫り始め、終着の水上駅へ至る頃には、風景が完全に山間のそれに変わっていた。
11時39分発の列車で北上を再開すると、この頃には乗客構成が鉄道ファンと少しの行楽客だけになっていた。間もなく新潟県との県境に近づくと、越後山脈を貫き日本海側・太平洋側を連絡する全長13kmの新清水トンネルへ突入し、途中で群馬県最奥の地中駅である有名な土合駅に停車した。コンクリに包まれた暗い空間がネットやテレビで見たままだと感心していると、乗客が一斉にドア付近へ集まり、「土合」と書かれた駅名標を銘々が撮影していった。一番乗りした少年が立派な一眼レフを首に下げていたり、私の向かい側に座っていた子連れの鉄道ファンがスマホの画面を見て大喜びしていたりした様を、半年以上経った今でも思い出せる。
やがて県境を越えトンネルを抜け、新潟県最初の駅・土樽駅に差し掛かると窓の外に白い地面が現れた。雪化粧を落とし始めたばかりの山々が空を縁取り、足元の水田にも雪が浮かぶ湯沢町の風景は、たった20分前まで観ていた群馬県のそれとは全く違う色をしていた。

その先、南魚沼の六日町盆地に敷かれた線形の良い鉄路を列車はすいすいと進み、日本海へ向けて流れる魚野川や信濃川と並走し始める。魚沼市の小出駅では会津若松市へ通じる只見線(8月に全線乗り通した)が分岐し、さらに3駅先の越後川口駅からは長野へ通じる飯山線(これも8月に乗り通した)が分岐する。小千谷市からは車内の人口密度も増し、信濃川が街の向こうへ去っていくと終着の長岡駅に到着した。すかさず乗り換えた列車は8分後にプラットフォームを離れ、越後平野を北へ進みながら人をさらに掻き込み、池袋を出てから約8時間後の14時56分、とうとう新潟駅に着いた。
1日目:中編(新潟市街)
すり抜ける隙間もないほど人の詰まったプラットフォームをじりじりと抜け出し、改札口を通過するとCoCoLoという名前の駅ビルに出た。CoCoLoは他の駅にもあるらしいので仙台のエスパルのような存在だろうか?
適当に新潟駅南口へ降りると、街灯にはアルビレックス新潟のフラッグが下げられていた。本当に新潟へ来たのだなと感じ入るのもそこそこに、遅い昼ご飯を食べられる場所を探すことにした。スマホで暫く調べると駅北側の万代口方面にあるタレカツ丼の店「とんかつ政ちゃん」がヒットしたので、そちらへ向かうことにした。

私はついぞ知らなかったのだが、この日は「さよなら新潟駅万代口バスターミナルの日」という大きなイベントが開かれていた。主役のバスターミナルは前月を以って65年間の役目を終えたばかりの名物だったそうで、もう少し調べてから赴くべきだったかと今は思う。

先刻見つけた店舗を探して暫く駅前を練り歩いた。しかしその姿をなかなか見つけられず、乗りたい列車の発車時刻15時50分が段々と迫ってきた。出発を遅らせられないかと急いで時刻表を確かめると、1時間半後の17時23分発が残っていた。酒田着が21時前と遅くなるが、幸い宿泊予定のホテルへはチェックインできる時刻のため、ここで予定を変更することにした。
ようやく入店できたのは15時半ごろのことだった。テーブル席に通され特製かつ丼を注文すると、届いたどんぶりは甘辛いタレの染みた豚カツが白米に5枚も乗った豪華仕様であった。柔らかくも食べ応えのあるカツ、とろみの付いた味噌汁はとても美味しかった。そうやって食べ進めていくと、白米の下から更に3枚のタレカツとタレの染みた白米が現れた。予想していなかった展開に私は感謝の気持ちでいっぱいになった。

満足して店を後にすると、出発までまだ1時間以上残っていた。どう過ごすか悩んだ末、私は海に近い万代島へ歩いてみることにした。ラーメン二郎新潟店を通り過ぎ、国道7号線へ出て、長岡で別れた時よりも大人しくなった信濃川と再会し、川に架かる柳都大橋脇の小道を下ると、いよいよ風景が港らしくなってきた。岸壁には漁船や海上保安庁の船舶が幾隻も停泊している。万代島の先端には新潟フェリーターミナルがあり、海の向こうの佐渡島へも船が出ている。いつもの暮らしは海と関係がないので、私は普段見られないものが見られて良かったと思った。結局そこには長居してしまい、甲府の時ほどではないが駅へは速足で戻ることになった。

1日目:後編(新潟~酒田)

私は17時23分発の列車に乗り、新潟駅を後にした。新発田駅までは白新線、そこからは羽越本線と路線が異なるがこの列車は村上まで直通運転となっていた。乗客が数えられるほどしか居ない中で私はボックス席にぽつんと座り、新潟市東部の夕暮れの街並みをぼけっと眺めていた。そのうち新発田駅を過ぎた辺りで日の入り時刻となり、車窓に映るのはほぼ車内の光だけになった。
この日撮った写真を座席で振り返るなどしているうち、18時41分、終着の村上駅で列車は止まった。乗換までは20分弱あったため構内をぶらぶらしていると、改札口付近の天井に鮭が丸ごと何尾も吊るされている光景に遭遇した。はらわたを抜かれて干物になっている鮭にはそれぞれ小学校名の書かれた札が下げられており、おそらく何かの行事で特産の塩引き鮭を作っているのだろうと想像した。

道中の駅には上品にデザインされたオレンジ色の駅名標が立てられていることがあった。立てられているのは主に新潟~酒田間を走る快速列車「海里」の停車駅で、調べると個室やイベントスペースなんかが充実した珍しい観光列車であった。村上から鶴岡までは海岸線を走るので、これに乗って眺望を楽しんだり、途中駅で降車して観光するのも良いかもしれない。

18時58分、乗り継いだディーゼルのワンマン列車が出発し漆黒の日本海沿いを北上し始めた。やがて山形県最初の駅・鼠ヶ関駅を過ぎ、鶴岡のあつみ温泉駅を越え、20時59分、この日の目的地である酒田駅に着いた。酒田駅の改札内には蒸気機関車の小規模な展示スペースが設けられており、9632のプレートと動輪1つが飾られていた。これは1914年に製造され晩年酒田を走っていた蒸気機関車9632号のもので、静態保存ののち2007年に解体されたと看板に書かれていた。また改札を出ると、待合室には羽越本線全通100周年の記念パネルが掲出されていた。

駅舎の上で輝く「酒田駅」の意匠は山居倉庫をイメージしたものだろうか。山居倉庫は約130年も前に建てられた米の保管倉庫群で、すぐ傍のケヤキ並木と共にドラマの撮影にも使われた実績もあり、現在は国指定史跡として酒田を代表する名所となっている。宿泊先へ向かう途中に山居倉庫があったので、立ち入ることこそ出来なかったがライトアップされた実物を見ることができた。無事宿に着くと、翌日が早いことを考え私はさっさと就寝した。


2日目:前編(酒田~秋田)
2日目、私は6時半ごろにホテルをチェックアウトした。列車の発車時刻までは1時間半ほどあるが、酒田を発つ前に最上川を見ておきたいと思ったからである。朝日を浴びて瑞々しい国道112号線を歩き、堤防を越えて出羽大橋の上に立つと、雄大な最上川が足の下を抜けて海へ向かう様子が目に映った。ここから2kmあまり西へ行けば日本海だ。また北を望めば、未だ厚い雪を頂く鳥海国定公園の峰々の聳え立つ様が見える。今日はあれを越えた先にある秋田へ行く。
時間こそ限られていたが、酒田ではヤマザワや山形銀行など、昔山形市に住んでいた頃よく見たものがあって懐かしい気持ちになれたことも良かった。


酒田駅で青春18きっぷへ印鑑をもらい、7時56分、秋田行きのワンマン列車に乗り酒田駅を出発した。この時点の車内は数えられるほどの乗客しかおらず、過半数が鉄道ファンのようであった。酒田駅を出ると間もなく周りがほとんど水田だけになり、水田地帯も過ぎると左手には日本海、右手には山という厳しい地形を縫うように進んだ。日本海の眺めは秋田の小砂川駅~上浜駅間、鳥海山方面の眺めは山形の遊佐駅~吹浦駅間が最も良いと思った。


ワンマン列車は出口が先頭車両の最も前のドアに限られ、乗客は整理券と運賃を集金箱に入れて出ることになっている。この方式の交通機関に乗るのは地元の路線バス以来で、途中下車をするわけでもないのにちょっと緊張した。
列車はにかほ市や由利本荘市を通過する間に乗客を溜め込んでいき、9時41分、いよいよ秋田駅に到着した。この旅の目玉・リゾートしらかみの出発までは1時間ほどあったので、少しだけ歩いて回ることにした。

(当日は2-1で勝ったらしい)
駅の改札口上部には横に長い電光掲示板が設置されており、広告が表示される。そこで秋田公立美術大学の(?)ピクセルアニメーションが流れ始めたため、暫く足を止めて眺めた。様々な妖怪が走り抜ける中、なまはげが紛れていたり柴犬が逆走したりと可愛い感じの作品だった。
駅の西口を出て5分ほどの所にある千秋公園は、江戸時代に秋田を治めた佐竹氏の居城・久保田城の跡地に整備されている。敷地内には佐竹史料館を始めとしてじっくり見るべき施設もあるのだが、残念ながら立ち入るには時間が足りなかった。

2日目:中編(リゾートしらかみ)
余裕を持って発車時刻の15分前に改札内へ戻り2番線へ下りると、スーツケースを引く観光客のグループや、立派なカメラを携えた乗客が列車の入線を待っていた。その風景の中、駅弁の移動販売が同じ場所で行われていた。本当に色々な弁当が持ち込まれていて、私はその中から「秋田比内地鶏弁当」を選択した。車内で食べたが、どの具も味がしっかり付いていてたいへん美味しかった。

発車時刻6分前、目の前にリゾートしらかみ3号として「くまげら」が入ってきた。くまげらとはブナ林に生息するキツツキ科の鳥の名前で、天然記念物かつ絶滅危惧種に指定されている。現在リゾートしらかみとしては3種類の編成が存在し、くまげらの他は「青池」「橅(ブナ)」という名前で呼ばれる(なおくまげらの車両が最も古く、橅が最も新しくてサービスも多い)。青池は青森県の白神山地西部に位置する十二湖のうち最も有名な池の名称、橅は白神山地がユネスコ世界遺産に登録された理由となった植物である。

リゾートしらかみは座席の前後間隔が非常に広く足を思いきり伸ばすことができ、乗り心地はJR東日本の列車の中でもかなり良い部類ではないかと思う。ボックスシート専門の車両もあるので、3人以上で一緒に楽しむことも出来る。最も人気なのは日本海側かつ窓側に相当するA席で、私もそこを予約していた。
10時50分過ぎ、くまげらは秋田駅を出発した。列車はまず奥羽本線に乗り、男鹿半島の付け根に位置する八郎潟に沿って北上する。1時間後に東能代駅へ到着すると、そこで進行方向を逆転させてようやく五能線へ進入する。実質的に逆走なので座席を自分で回転させる必要があり、やり方を調べていなかったせいで少々手間がかかった。

列車は右へ進んでいるが、この後は奥に見える五能線を左へ進む
五能線で最初の停車駅は能代駅だった。近所にバスケで有名な能代工業高校があったこの駅では、プラットフォームで1投だけバスケのフリースロー体験ができる。シュートが決まれば粗品を受け取れるようだが、私は外して何も貰えなかった。粗品の正体が気になる読者は是非チャレンジしてほしい。そのほか、せっかくなので改札口前の売店でいぶりがっこを買ったりもした。
5駅先の東八森を過ぎた12時半頃、日本海が列車から見え始めた。この日は晴れて海も穏やか、漣が磯を撫でる様は枯山水を想わせた。やがて秋田県最後の駅・岩舘駅を過ぎると列車と海の間を遮るものはもはや失せ、ここから鰺ヶ沢へ至るまでの2時間ほどは車窓がほとんど空と海の青に染まることとなる。
青森との県境を越える頃、「この後絶景ポイントを徐行運転するからしっかり見てほしい」という旨の車内放送があった。正直今までも良い眺めだったがどうなるのかと思っていると、双子の短いトンネルを抜けたところで列車が大きく減速した。そこにあったものは、延々続く国道101号で縁取られた海岸と、それを海側から飾り立てる奇岩の大群、それらをさらに取り囲む大海であった。この辺りの地名は大間越といい、絶景ポイントと言われる理由は五能線区間の中でも特に多くの奇岩が顔を見せているからかと思っている。実際に目にすると確かに圧巻で、リゾートしらかみでなくとも自動車でここをドライブしたらさぞ楽しいだろうと思う。

絶景ポイントを過ぎると列車は十二湖駅やウェスパ椿山駅で停車し、いくらか乗客の出入りがあった。十二湖駅は青池へ、ウェスパ椿山駅は不老不死温泉への最寄り駅である。なお駅名の由来になったウェスパ椿山は大規模な複合施設で、見所も豊富だったそうだが物産館コロボックルを除き2020年に営業を終了してしまっている。


その後、13時半頃に列車は深浦駅へ到着した。近世において大坂と北海道の間の水運を北前船が担っていたが、深浦はその北前船の風待ち港として栄えた地域だった。現代では夕日が映える場所としても有名で、他にも深浦町としてはクロマグロの漁獲量が青森県トップという側面も持つ。
この先には230年前の大地震で隆起した広大な岩棚・千畳敷海岸がある。最寄り駅に停車中は千畳敷を自由に散策してよいことになっており、私はそれを楽しみにしていた。…が、列車は深浦駅からなかなか出発しない。実はこの日の昼、千畳敷の先の区間で線路内発煙が発生したために他の列車のダイヤが大きく乱れていた。実際の車内放送を覚えていないのだが、私の乗るリゾートしらかみ3号もこの影響を受けたはずである。定刻を10分以上過ぎて列車はようやく発車したが、この遅れのせいで千畳敷の散策時間はあえなくカットされてしまった。


そして千畳敷を過ぎると、列車は本来通過する次の駅・北金ヶ沢駅に臨時停車し、また10分間ほど車両点検が行われた。こういうハプニングも旅行にはつきものだ、と思うことにした。


北金ヶ沢駅を出て15分ほどすると鯵ヶ沢駅に停車した。進行方向左手に見えていた日本海とはここでお別れし、今度は岩木山を右手に望みながら津軽平野を南下して弘前へ向かう。鯵ヶ沢からは車内のイベントスペースで津軽三味線の演奏が行われた。演奏された曲は順に、りんご節、津軽じょんがら節、津軽甚句、りんご節(歌唱付き)であった。私は最後の歌唱あり版のりんご節が最も好きだ。
この区間では三味線以外にも津軽弁の語り部、または津軽伝統の人形芝居が実演されるパターンがあるらしい。

五所川原駅では津軽鉄道の車両を遠くに見ることが出来た。津軽鉄道線はここから津軽半島の中里までを結ぶ私鉄路線で、冬季に運行されるストーブ列車が有名である。古めかしい列車の中でスルメを炙って食べたり、お酒を嗜んだり出来るそうなので何かのついでに乗ってみるのもよさそう。
そしていつの間にか遅れを取り戻した列車は15時半過ぎに五能線の終点・川部駅に停車、続けて15時50分ごろにリゾートしらかみ3号の終着駅・弘前駅に到着した。川部では東能代のときと同じように列車がスイッチバックし、もはや座席をどちらに向けるべきか分からなくなった。なので弘前では乗客が思い思いの向きに座席を回転させて去っていった。

五能線を乗り通して思ったのは、昔の人はこんな険しいところによく線路を通したなということと、やはり乗りに来て大正解だったということだ。白神山地に日本海、目の前に迫る荒々しい海岸といった自然の産物だけでなく、一時下車して出来る体験や車内での催し物もここにしかないものだった。いつになるか分からないが、今度は夕日の見える時間帯に来てみたいと思う。
2日目:後編(弘前~本八戸)
ここからは奥羽本線で青森へ移動し、さらに青い森鉄道と八戸線を乗り継いで本八戸の宿へ向かう予定にしていた。予約した宿のある八戸市の中心街は新幹線の停まる八戸駅ではなく、その先の本八戸駅が最寄りだからである。ただ青森駅に着くと少し歩きたい気分になったため、次の乗車予定を1時間遅らせることにした。
青森駅周辺ではリンゴを扱う土産物店が複数入居するA-FACTORYや、青函連絡船が活躍していた頃の遺構などが目を引いた。特にそこで係留されている八甲田丸は青函連絡船として最も長く働いた船で、料金を払って船内の操舵室や車両甲板などの展示物を見ることができる。今回は時間が足りなかったが、次に青森へ来る機会があれば入ってみたい。(今思えば無理して乗り継ぎを2時間遅らせれば入れた...)

青森駅から八戸駅までは第三セクターの青い森鉄道で移動するのだが、JRの路線に乗り継ぐ(つまり野辺地駅から大湊線へ、八戸駅から八戸線へ行く)場合に限って青春18きっぷで乗車可能というルールがあった。改札口を通らずにプラットフォームを行き来できるからそうなっているのだと思うが、何だかタダ乗りしているようで複雑な気持ちになった。ワンマン列車で青森を発ったのが18時頃と日没間近だったため、線路が野辺地の手前で陸奥湾に最接近する頃には窓から何も見えなくなってしまった。強い眠気に抗いながら、20時半過ぎに八戸線の本八戸駅へ到着した。

霧が出て少し肌寒い空気の中、道なりに進むと市の中心の商店街である三日町に出た。日曜夜ということでほとんどの店が営業しておらず人通りも少なく、私は眠る街の中をすぐ抜けようとした。しかしそこで、上着のポケットに入れていたはずの財布が無いことに気付いた。実は乗ってきた久慈行きの列車に財布を落としてしまっており、このときの私は18きっぷを除き無一文なのだった。幸い宿泊費をオンラインで決済していたから野宿にはならなかったが、財布が見つからなかったらどうやって帰ろうなどと苦悩しながら就寝する羽目になった。
3日目(本八戸~東京)
私は本八戸駅で青春18きっぷへ4つ目の印鑑を貰い、8時45分だったかの列車で八戸駅へ向かった。財布が八戸駅に届いていてほしいという淡い願望を抱いて改札の窓口へ赴くと、実際に私の財布はそこで保管されていた。前日乗車した列車の運転手が、折り返しの列車で届けてくれていたのだった。戻ってきた財布は紙幣が全て抜かれていたものの、その他の小銭などはそのままであった。
緊張が解けてすっかり気の抜けた私は、この後の予定を切り上げてさっさと新幹線で東京へ戻ることにしてしまった。クレジットカードで切符を買い10時17分の新幹線に乗り、東京駅に着いたのは13時過ぎであった。2日間で計20時間以上掛けて東日本を半周してきたわけだが、もう半周は3時間で完了したことになる。やはり新幹線は速い。

まとめ
リゾートしらかみは乗りに行って本当に良かった。青春18きっぷを使った大回りの行程も、スーパーの試食レベルの量ながら新しい知識を得ることに大きく寄与した。3日間とも運よく概ね快晴であったし、何より行ったことのない場所に足を運ぶことは楽しいということを再確認できた。
しかし、途中の乗り継ぎ地点にあった観光スポットをほとんどスルーしたことはかなり惜しまれる。旅の一番の目的を無事果たしたとはいえ、特に目の前まで来ていた酒田の山居倉庫、秋田の千秋公園、青森の八甲田丸などは本来時間を費やすべき場所だ。私はゆっくりな旅をしているように見えて、実はだいぶせっかちな行動を自分に強いていたことを理解する機会にもなった。将来的にちゃんと時間と予算を確保して、今回行けなかった名所を回れたらよいと思う。
最後に
貴重品は油断せずポケットでなく口の閉まる入れ物にしまいましょう。
弐寺の譜面レベル推論モデルを作った
はじめに
弐寺のSP譜面レベル(1~12の12段階)を推論するモデルを作りましたので公開します。本記事は音楽ゲームとニューラルネットワークの両方に興味がある人向けです。
要約
- 譜面を時系列データと捉え、LSTMを使ったニューラルネットワークによりレベルの推論を行いました。
- 学習の結果、検証データの正解率は 65.0% となりました。
- 信頼性はさておき、任意のSP譜面にレベルを自動で付与することが可能になりました。
- ソースとモデル(github)
譜面の学習・推論方法
譜面のレベルは曲の最後にどれだけゲージを残しやすいかで決まると考えられます。全体の99%が簡単でも最後の1小節が難しい譜面はクリアも難しい(=高レベル)ですし、初めの方が難しくても残りが簡単であればクリアも易しく(=低レベルに)なります。従ってレベルの判定には、譜面そのものに加えて時間の考慮も必要と考えられます。今回は譜面を時系列データと捉え、LSTMを使ってレベルを推論することにしました。
譜面フォーマット
譜面をネットワークに入力するため、以下のようなnumpy.ndarrayの2次元配列へ落とし込むことにしました。

配列の1次元目はノーツのタイミングを表します。3連符や32分等の細かいノーツ配置に対応するため、タイミングの最小単位を4分音符の48分の1(192分音符相当)としました。
また2次元目は譜面のレーン(ターンテーブル+1~7鍵)とBPMを表します。配列のBPM部分を除く各要素の値は以下のように決めました。
| ノーツ無し | ノーツあり | CN・HCN・BSS始点/終点 | CN・HCN・BSS途中 | |
|---|---|---|---|---|
| 値 | 0 | 1 | 1 | 0.5 |
※CN=チャージノート、HCN=ヘルチャージノート、BSS=バックスピンスクラッチ
上記の要領で作成した全小節をひと繋ぎにして譜面データは完成です。(図1において1次元目の実際のインデックスは 62小節*192=11904 を加算した値となります。)
ネットワーク
推論を行うネットワークを以下のようにChainerで実装しました。
model.py
from chainer import Chain
import chainer.links as L
import chainer.functions as F
class Estimator(Chain):
def __init__(self):
super(Estimator, self).__init__()
with self.init_scope():
self.layer1 = L.NStepLSTM(2, 1728, 256, 0.3)
self.layer2 = L.Linear(256, 12)
def __call__(self, x):
_, _, h = self.layer1(None, None, x)
h = [t[-1] for t in h]
# 後でPCAやるために隠れ層を保持できるようにした
self._h = F.stack(h)
return self.layer2(self._h)
updater.py
from chainer import reporter
from chainer.training import StandardUpdater
import chainer.functions as F
def concat_batch(batch: list):
scores = []
levels = []
for (score, level) in batch:
scores.append(score)
levels.append(level)
return scores, levels
class EstimatorUpdater(StandardUpdater):
def __init__(self, **kwargs):
super(EstimatorUpdater, self).__init__(**kwargs)
def update_core(self):
# イテレータには譜面データと正解のレベルを格納している
scores, levels = concat_batch(self.get_iterator("main").next())
opt = self.get_optimizer("main")
est = opt.target(scores)
lv = opt.target.xp.array(levels, dtype=int)
loss = F.softmax_cross_entropy(est, lv)
reporter.report({
"train/loss": loss,
"train/acc": F.accuracy(est, lv)
})
opt.target.cleargrads()
loss.backward()
loss.unchain_backward()
opt.update()
学習の流れは以下の通りです。
- 読み込んだ譜面データのshapeを予め (n, 9) → (n/192, 192*9) と変形しておく(n=譜面の長さ)→ 4/4拍子換算で1小節ずつLSTMに入力できるようになる
- BPMの値を100で割る ← そのままだとノーツ部分の値が小さすぎるためか学習が進まなかったので、BPMの値をノーツ部分に近づけることにしたため
- (model.py) LSTMに譜面の初めから4/4拍子換算で1小節ずつ入力する
- (model.py) 譜面全体を入力し終えた時のLSTMからの出力をもとに譜面を12レベルに分類する
- (updater.py) 分類結果と正解のレベルの差が小さくなるように学習を進める
譜面の用意
今回の学習に使用する譜面データはTexTage様が公開しているページを参考にして作成しました。学習に使用したのは、現行のAC筐体でプレイ可能かどうかにかかわらず12段階のレベルが付いたことが一度でもある全ての譜面です。譜面の学習データ・検証データ・テストデータへの振り分けは、曲のAC初収録バージョンを基準としました。
| 曲の収録 | 振り分け | 譜面数 |
|---|---|---|
| CANNON BALLERS以前・家庭用限定 | 学習データ9:検証データ1 (ランダム) | 学習4228、検証464 |
| Rootage以降 | 全てテストデータ | 473 |
結果

途中から過学習の傾向がみられますがちゃんと学習できているようです。検証時のlossが最小だった48epochで検証データの65.0%を正解し、98.0%が誤差1レベル以内に収まりました。この48epoch時点のモデルにテストデータを入力した結果、公式レベルと推論結果が一致したものは315譜面、不一致だったものは158譜面でした。
不一致だった譜面の中にはBEMANI Wiki 2nd2にコメントが書き込まれているものもありました。以下は評価がWikiのコメントと概ね一致した譜面の一例です。
| 譜面 | 公式のLv | 推論結果のLv | Wikiのコメント |
|---|---|---|---|
| CODE:∅(N) | 5 | 6 | ☆6中位~上位相当 |
| dAuntl3ss(N) | 6 | 5 | ☆5レベル |
| グラナダの風(H) | 8 | 7 | ☆7程度の密度 |
| Backyard Stars(H) | 8 | 9 | ☆9下位~中位レベル |
| Shiva(A) | 11 | 10 | ☆11にしては密度低め |
| Necroxis Girl(A) | 11 | 12 | ☆12下位レベル |
| Primitive Vibes(A) | 12 | 11 | ☆11上位レベル |
中には個人的に明らかにおかしいと思われた推論結果もあったので紹介します。
| 譜面 | 公式のLv | 推論結果のLv |
|---|---|---|
| ONIGOROSHI(N) | 6 | 9 |
| IDC feat.REVERBEE(Mo'Cuts Ver)(H) | 9 | 8 |
| Silly Love(A) | 10 | 9 |
| LADYBIRD(A) | 11 | 10 |
| 最小三倍完全数(A) | 12 | 11 |
まとめ
譜面をnumpy.ndarray形式に落とし込み、LSTMを利用することによって譜面のレベルを推論することが出来ました。今回の結果をひとつの指標として今後も取り組んでいけたらと思っています。課題としては、
- 過学習対策をする必要がある
- 10小節に満たないような短い譜面や300小節を超えるような長すぎる譜面を学習していないため、そのような譜面のレベルを正しく推論できるか分からない
- そもそも学習に使用した譜面の公式レベル設定に詐称/逆詐称が含まれており、学習データの質の面で改善の余地がある
...といったところでしょうか。このモデルを作るために試行錯誤する間、最新作でレベルの変更された譜面が出たりChainerの開発が終了したりしましたが、私は元気です。
おまけ
個人的にLSTMからの出力の状態が気になったので、テストデータそれぞれを入力したときの隠れ層の状態(model.py のself._h)を集めて主成分分析を行いました。使用したモデルは上述した検証時のlossが最小だったときのものです。

色は推論結果のレベルを表します。(☆1=赤→橙→黄→緑→青→紫=☆12)
多少のばらつきはありますが何らかの規則に従ってキレイに並んでいるように見えます。試しに推定結果☆10(青色)の譜面の中から☆9(薄い青色)付近、中央、☆11(青紫色)付近を抜き出して尤度を比較してみました。
※ここでいう尤度はモデルの出力層にソフトマックスを適用した値を指します。

| 曲名 | ☆9の尤度 | ☆10の尤度 | ☆11の尤度 |
|---|---|---|---|
| ToyCube Pf.(RX-Ver.S.P.L.)(A) | 0.477 | 0.501 | 0.014 |
| Crank It(A) | 0.112 | 0.868 | 0.017 |
| EVANESCENT(H) | 0.028 | 0.922 | 0.048 |
| THE DAY OF JUBILATIONS(H) | 0.013 | 0.816 | 0.168 |
| ZENDEGI DANCE(A) | 0.008 | 0.511 | 0.471 |
成分が☆9に近い位置から☆11に近い位置へ移るにつれて、尤度のピークも☆9付近から☆11付近へ移動しています。これを利用して曲の間に難しさの序列を付け、地力表みたいな物を作れるのではないかとも思ったりしています。(全てのプレイヤーに当てはまるようなものを作るのは無理だと思いますが...)