Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第11章 from dsets import LunaDataset についてエラー #14

Open
146790g opened this issue Nov 24, 2021 · 4 comments
Open

第11章 from dsets import LunaDataset についてエラー #14

146790g opened this issue Nov 24, 2021 · 4 comments

Comments

@146790g
Copy link

146790g commented Nov 24, 2021

!pip install SimpleITK
!pip install diskcache

として、次に、『from dsets import LunaDataset』を実行すると、エラーとなります。
エラー内容は、以下のとおりです。御社のGithubに掲載されているコードをそのまま実行しているのですが、
エラーとなっており、このようなエラー内容は、これまで見たこともなく、解決ができません。
解決策についてご教示いただけますと幸いです。

解析環境: Google Colaboratory
/usr/local/lib/python3.7/dist-packages/diskcache/core.py in _con(self)
637 try:
638 select = 'SELECT key, value FROM Settings'
--> 639 settings = con.execute(select).fetchall()
640 except sqlite3.OperationalError:
641 pass

DatabaseError: database disk image is malformed

P.S.
『Pytorchによる発展ディープラーニング』は、大変すばらしい名著と思いますが、この本は、
Deep Learningの本質以外に、枝葉末節に、多くの見たこともない複雑なコードを頻繁に利用しており、上級者で
ないと読めないと思います。上級者であれば、本をよまなくてもGithubのソースコードから
読んで学習できるので、書籍として、あたかも入門者にむけて学習用に作成されているというのが
よくないと思います。
もし、Deep Learningに興味をもって、最初にこの本を読まれた方は、必ず挫折すると思います。

@Gin5050
Copy link
Owner

Gin5050 commented Dec 4, 2021

146790g様
ご質問ありがとうございます。
そしてご連絡が遅くなり申し訳ありません。

エラーについてですが、こちらで再現ができておりません。
エラー再現のためにお手数ですが以下の情報を教えていただけないでしょうか

  • colabで実行時のフォルダ構成
  • 実行時のコード
  • その他実行に至るまでに行ったことなど

(P.Sの内容に関して)
本書へのご感想誠にありがとうございます。
 
本書はp. iiiの想定読者で記載している通り、Pythonの構文などには慣れていてる読者を想定し、
さらにDeep LearningとPyTorchを学びたい方に向けて執筆されました。
 
第1部を通してDeep Learningをはじめて学ぶ方向けに丁寧に執筆されてはいますが、
P.Sで記載いただいた内容には、翻訳者の私たちも共感する部分があります。
 
日本語版として、本Isuueコーナーで対応できる部分は今後も引き続き対応し、読者の皆様の理解のサポートに尽力させていただきます。
本文や構成・内容そのものについては、原著者らより改訂版を執筆に取りかかると聞いた際に、上記いただいた意見を届けさせていただきます。
 
今後ともどうぞ宜しくお願い致します。
 

@146790g
Copy link
Author

146790g commented Dec 7, 2021

ご丁寧な回答をありがとうございます。

実際、貴Githubにて公開されているp2_run_everything.ipynbの
run('p2ch11.training.LunaTrainingApp', '--epochs=1')のコマンドラインを実行したときには、
p2ch11ディレクトリ直下のtraining.pyのファイル内に、『from .dsets import LunaDataset』があり、
このコードが実行されることになります。

run('p2ch11.training.LunaTrainingApp', '--epochs=1')自体は、エラーなく動作することが確認されています。

しかし、私自身の学習のため、そのtraining.pyのファイル内のプロセスを詳細に調査するために、
以下のようなipynbファイルを作成して読み込んだところ、エラーとなります。
そのipynbファイルは、p2ch11の直下に置いています。

<エラーが発生するgithubページ>
https://github.com/146790g/pytorch_advanced/blob/master/Ch11_5_List11_10_11_11_11_12_Training_02_Error_version.ipynb

一方、dsets.pyを以下に記述したとおり、コードをdsets2.pyに書き換えたところエラーがなくなります。
エラーが消滅した理由はわかりません。

<エラーが生じないgithubページ>
https://github.com/146790g/pytorch_advanced/blob/master/Ch11_5_List11_10_11_11_11_12_Training_02_Correct_version.ipynb

<以下のファイルをdsets2.pyと命名して、p2ch11のディレクトリの直下に保存>

from util.disk import getCache
from collections import namedtuple
from torch.utils.data import Dataset
import copy
import csv
import functools
import glob
import os
import random

from collections import namedtuple

import SimpleITK as sitk
import numpy as np

import torch
import torch.cuda
from torch.utils.data import Dataset
from util.util import XyzTuple, xyz2irc
from util.disk import getCache
from util.logconf import logging

raw_cache = getCache('part2ch10_raw')

CandidateInfoTuple = namedtuple(
'CandidateInfoTuple',
'isNodule_bool, diameter_mm, series_uid, center_xyz',
)

def getCandidateInfoList(requireOnDisk_bool=True):
# We construct a set with all series_uids that are present on disk.
# This will let us use the data, even if we haven't downloaded all of
# the subsets yet.
mhd_list = glob.glob('/content/drive/MyDrive/Colab Notebooks/Pytorch CT Lung Cancer/deep-learning-with-pytorch-ja-main/data-unversioned/part2/luna/subset0/*.mhd')
presentOnDisk_set = {os.path.split(p)[-1][:-4] for p in mhd_list}

diameter_dict = {}
with open('/content/drive/MyDrive/Colab Notebooks/Pytorch CT Lung Cancer/deep-learning-with-pytorch-ja-main/data/part2/luna/annotations.csv', "r") as f:
    for row in list(csv.reader(f))[1:]:
        series_uid = row[0]
        annotationCenter_xyz = tuple([float(x) for x in row[1:4]])
        annotationDiameter_mm = float(row[4])

        diameter_dict.setdefault(series_uid, []).append(
            (annotationCenter_xyz, annotationDiameter_mm)
        )

candidateInfo_list = []
with open('/content/drive/MyDrive/Colab Notebooks/Pytorch CT Lung Cancer/deep-learning-with-pytorch-ja-main/data/part2/luna/candidates.csv', "r") as f:
    for row in list(csv.reader(f))[1:]:
        series_uid = row[0]

        if series_uid not in presentOnDisk_set:
            continue

        isNodule_bool = bool(int(row[4]))
        candidateCenter_xyz = tuple([float(x) for x in row[1:4]])

        candidateDiameter_mm = 0.0
        for annotation_tup in diameter_dict.get(series_uid, []):
            annotationCenter_xyz, annotationDiameter_mm = annotation_tup
            for i in range(3):
                delta_mm = abs(candidateCenter_xyz[i] - annotationCenter_xyz[i])
                if delta_mm > annotationDiameter_mm / 4:
                    break
            else:
                candidateDiameter_mm = annotationDiameter_mm
                break

        candidateInfo_list.append(CandidateInfoTuple(
            isNodule_bool,
            candidateDiameter_mm,
            series_uid,
            candidateCenter_xyz,
        ))

candidateInfo_list.sort(reverse=True)
return candidateInfo_list

class Ct:
def init(self, series_uid):
mhd_path = glob.glob(
'/content/drive/MyDrive/Colab Notebooks/Pytorch CT Lung Cancer/deep-learning-with-pytorch-ja-main/data-unversioned/part2/luna/subset0/{}.mhd'.format(series_uid))[0]

    ct_mhd = sitk.ReadImage(mhd_path)
    ct_a = np.array(sitk.GetArrayFromImage(ct_mhd), dtype=np.float32)

    # CTs are natively expressed in https://en.wikipedia.org/wiki/Hounsfield_scale
    # HU are scaled oddly, with 0 g/cc (air, approximately) being -1000 and 1 g/cc (water) being 0.
    # The lower bound gets rid of negative density stuff used to indicate out-of-FOV
    # The upper bound nukes any weird hotspots and clamps bone down
    ct_a.clip(-1000, 1000, ct_a)

    self.series_uid = series_uid
    self.hu_a = ct_a

    self.origin_xyz = XyzTuple(*ct_mhd.GetOrigin())
    self.vxSize_xyz = XyzTuple(*ct_mhd.GetSpacing())
    self.direction_a = np.array(ct_mhd.GetDirection()).reshape(3, 3)

def getRawCandidate(self, center_xyz, width_irc):
    center_irc = xyz2irc(
        center_xyz,
        self.origin_xyz,
        self.vxSize_xyz,
        self.direction_a,
    )

    slice_list = []
    for axis, center_val in enumerate(center_irc):
        start_ndx = int(round(center_val - width_irc[axis]/2))
        end_ndx = int(start_ndx + width_irc[axis])

        assert center_val >= 0 and center_val < self.hu_a.shape[axis], repr([self.series_uid, center_xyz, self.origin_xyz, self.vxSize_xyz, center_irc, axis])

        if start_ndx < 0:
            # log.warning("Crop outside of CT array: {} {}, center:{} shape:{} width:{}".format(
            #     self.series_uid, center_xyz, center_irc, self.hu_a.shape, width_irc))
            start_ndx = 0
            end_ndx = int(width_irc[axis])

        if end_ndx > self.hu_a.shape[axis]:
            # log.warning("Crop outside of CT array: {} {}, center:{} shape:{} width:{}".format(
            #     self.series_uid, center_xyz, center_irc, self.hu_a.shape, width_irc))
            end_ndx = self.hu_a.shape[axis]
            start_ndx = int(self.hu_a.shape[axis] - width_irc[axis])

        slice_list.append(slice(start_ndx, end_ndx))

    ct_chunk = self.hu_a[tuple(slice_list)]

    return ct_chunk, center_irc

def getCt(series_uid):
return Ct(series_uid)

def getCtRawCandidate(series_uid, center_xyz, width_irc):
ct = getCt(series_uid)
ct_chunk, center_irc = ct.getRawCandidate(center_xyz, width_irc)
return ct_chunk, center_irc

import glob
import csv
import random
class LunaDataset(Dataset):

def __init__(self,
             val_stride=0,
             isValSet_bool=None,
             series_uid=None,
        ):
    #self.candidateInfo_list = copy.copy(getCandidateInfoList())
    self.candidateInfo_list = getCandidateInfoList(requireOnDisk_bool=False)

    if series_uid:
        self.candidateInfo_list = [
            x for x in self.candidateInfo_list if x.series_uid == series_uid
        ]

    if isValSet_bool:
        assert val_stride > 0, val_stride
        self.candidateInfo_list = self.candidateInfo_list[::val_stride]
        assert self.candidateInfo_list
    elif val_stride > 0:
        del self.candidateInfo_list[::val_stride]
        assert self.candidateInfo_list
        
    random.shuffle(self.candidateInfo_list)



def __len__(self):
    return len(self.candidateInfo_list)

def __getitem__(self, ndx):
    candidateInfo_tup = self.candidateInfo_list[ndx]
    width_irc = (32, 48, 48)

    candidate_a, center_irc = getCtRawCandidate(
        candidateInfo_tup.series_uid,
        candidateInfo_tup.center_xyz,
        width_irc,
    )

    candidate_t = torch.from_numpy(candidate_a)
    candidate_t = candidate_t.to(torch.float32)
    candidate_t = candidate_t.unsqueeze(0)

    pos_t = torch.tensor([
            not candidateInfo_tup.isNodule_bool,
            candidateInfo_tup.isNodule_bool
        ],
        dtype=torch.long,
    )

    return (
        candidate_t,
        pos_t,
        candidateInfo_tup.series_uid,
        torch.tensor(center_irc),
    )

以上となります。

どうぞよろしくお願い申し上げます。 

@Gin5050
Copy link
Owner

Gin5050 commented Dec 19, 2021

146790g 様

詳細な情報提供ありがとうございます。
また、ご回答が遅くなり申し訳ありません。

エラーについてですが、キャッシュが作成されていない(もしくは破損している)ことが原因だと思われます。
いただいた情報を見ると、エラーが出たケースと出てないケースではキャッシュの参照先が異なります。
dsets.pyの場合

---> 28 raw_cache = getCache('part2ch11_raw')

dsets2.pyの場合

raw_cache = getCache('part2ch10_raw')

解決策として、dsets.pyの該当箇所をdsets2.pyと同じにする、もしくは'part2ch11_raw’のキャッシュを再作成する方法でうまくいくか試していただけないでしょうか。
’part2ch11_raw’の再作成はp2_run_everything.ipynbnrun('p2ch11.prepcache.LunaPrepCacheApp’)で実行できます。
’part2ch11_raw’がすでに存在している場合は、念のため一度キャッシュを削除してから再作成を実行ください。
キャッシュの削除は同じくp2_run_everything.ipynbncleanCache()のコメントアウトを外すと実行できます。

お手数をおかけしますが、どうぞよろしくお願い致します。

@146790g
Copy link
Author

146790g commented Jan 20, 2022

ご丁寧な回答をいただき誠にありがとうございます。
'part2ch11_raw’のキャッシュを再作成する方法にて、対処したところ、解決いたしました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants