การวิเคราะห์ราคา Polkadot 13 ก.ย.

Convolutional Neural Network – การใช้งาน PyTorch บน CIFAR-10 Dataset

โหนดต้นทาง: 1866263

บทความนี้เผยแพร่โดยเป็นส่วนหนึ่งของไฟล์ Blogathon วิทยาศาสตร์ข้อมูล

บทนำ

ซิฟาร์ 10 | pytorch เครือข่ายประสาท Convolutional
                                    1 รูปภาพ

โครงข่ายประสาทเทียมแบบ Convolutional หรือที่เรียกว่า ConvNets ได้รับการแนะนำครั้งแรกในปี 1980 โดย Yann LeCun นักวิจัยด้านวิทยาการคอมพิวเตอร์ที่ทำงานอยู่เบื้องหลัง LeCun สร้างขึ้นจากผลงานของ Kunihiko Fukushima นักวิทยาศาสตร์ชาวญี่ปุ่น ซึ่งเป็นเครือข่ายพื้นฐานสำหรับการจดจำภาพ

CNN เวอร์ชันเก่าเรียกว่า LeNet (ตามหลัง LeCun) สามารถดูตัวเลขที่เขียนด้วยลายมือได้ CNN ช่วยค้นหารหัส PIN จากไปรษณีย์ แต่ถึงแม้จะเชี่ยวชาญ ConvNets ก็ยังใกล้ชิดกับคอมพิวเตอร์วิทัศน์และปัญญาประดิษฐ์เพราะพวกเขาประสบปัญหาสำคัญ: พวกเขาไม่สามารถปรับขนาดได้มาก CNN ต้องการข้อมูลจำนวนมากและรวมทรัพยากรเพื่อให้ทำงานได้ดีสำหรับรูปภาพขนาดใหญ่

ในขณะนั้น วิธีนี้ใช้ได้กับภาพความละเอียดต่ำเท่านั้น Pytorch เป็นห้องสมุดที่สามารถทำการเรียนรู้เชิงลึกได้ เราสามารถใช้สิ่งนี้เพื่อทำโครงข่ายประสาทเทียมแบบ Convolutional โครงข่ายประสาทเทียมประกอบด้วยเซลล์ประสาทเทียมหลายชั้น เซลล์ประสาทสังเคราะห์ การจำลองที่ซับซ้อนของคู่ขนานทางชีววิทยา เป็นฟังก์ชันทางคณิตศาสตร์ที่คำนวณมวลถ่วงน้ำหนักของอินพุตหลายตัวและการกระตุ้นมูลค่าผลิตภัณฑ์

เครือข่ายประสาท Convolutional pytorch
2 รูปภาพ

ภาพด้านบนแสดงโมเดล CNN ที่ใช้ภาพที่คล้ายตัวเลข 2 และให้ผลลัพธ์ของตัวเลขที่แสดงในภาพเป็นตัวเลข เราจะหารือในรายละเอียดว่าเราได้สิ่งนี้มาอย่างไรในบทความนี้

CIFAR-10 เป็นชุดข้อมูลที่มีคอลเลกชั่นรูปภาพ 10 คลาสที่แตกต่างกัน ชุดข้อมูลนี้ใช้กันอย่างแพร่หลายเพื่อการวิจัยเพื่อทดสอบโมเดลการเรียนรู้ของเครื่องต่างๆ และโดยเฉพาะอย่างยิ่งสำหรับปัญหาการมองเห็นด้วยคอมพิวเตอร์ ในบทความนี้ เราจะพยายามสร้างแบบจำลองโครงข่ายประสาทเทียมโดยใช้ Pytorch และทดสอบกับชุดข้อมูล CIFAR-10 เพื่อตรวจสอบความถูกต้องของการคาดการณ์ที่สามารถรับได้

การนำเข้าไลบรารี PyTorch 

นำเข้า numpy เป็น np นำเข้าแพนด้าเป็น pd
นำเข้าคบเพลิง นำเข้าคบเพลิง.nn.functional เป็น F จากชุดข้อมูลนำเข้าคบเพลิง แปลงจากคบเพลิง นำเข้า nn นำเข้า matplotlib.pyplot เป็น plt นำเข้าจำนวนเป็น np นำเข้าทะเลเป็น sns #จาก tqdm.notebook นำเข้า tqdm จาก tqdm นำเข้า tqdm

ในขั้นตอนนี้ เรานำเข้าไลบรารีที่จำเป็น เราจะเห็นได้ว่าเราใช้ NumPy สำหรับการดำเนินการเชิงตัวเลขและแพนด้าสำหรับการดำเนินการเฟรมข้อมูล ไลบรารีคบเพลิงใช้เพื่อนำเข้า Pytorch

Pytorch มีองค์ประกอบ nn ที่ใช้สำหรับนามธรรมของการดำเนินการและฟังก์ชันการเรียนรู้ของเครื่อง สิ่งนี้ถูกนำเข้าเป็น F. ใช้ไลบรารี torchvision เพื่อให้เราสามารถนำเข้าชุดข้อมูล CIFAR-10 ไลบรารีนี้มีชุดข้อมูลรูปภาพจำนวนมากและมีการใช้กันอย่างแพร่หลายสำหรับการวิจัย สามารถนำเข้าการแปลงเพื่อให้เราสามารถปรับขนาดรูปภาพให้มีขนาดเท่ากันสำหรับรูปภาพทั้งหมด tqdm ถูกใช้เพื่อให้เราสามารถติดตามความคืบหน้าระหว่างการฝึกอบรมและใช้สำหรับการสร้างภาพข้อมูล

อ่านชุดข้อมูลที่จำเป็น

trainData = pd.read_csv('cifar-10/trainLabels.csv') trainData.head()

เมื่อเราอ่านชุดข้อมูลแล้ว เราจะเห็นป้ายต่างๆ เช่น กบ รถบรรทุก กวาง รถยนต์ เป็นต้น

วิเคราะห์ข้อมูลด้วย PyTorch

print("จำนวนคะแนน:",trainData.shape[0]) print("จำนวนคุณสมบัติ:",trainData.shape[1]) พิมพ์ ("คุณสมบัติ:",trainData.columns.values) พิมพ์ ("จำนวน ค่าที่ไม่ซ้ำ") สำหรับ col ใน trainData: print(col,":",len(trainData[col].unique())) plt.figure(figsize=(12,8))

Output:

จำนวนคะแนน: 50000 จำนวนคุณสมบัติ: 2 คุณสมบัติ: ['id' 'label'] จำนวนค่าที่ไม่ซ้ำ id : 50000 label : 10

ในขั้นตอนนี้ เราวิเคราะห์ชุดข้อมูลและเห็นว่าข้อมูลรถไฟของเรามีแถวประมาณ 50000 แถวพร้อมรหัสและป้ายกำกับที่เกี่ยวข้อง มีทั้งหมด 10 คลาสในชื่อ CIFAR-10

รับชุดการตรวจสอบความถูกต้องโดยใช้ PyTorch

จาก torch.utils.data นำเข้า random_split val_size = 5000 train_size = len (ชุดข้อมูล) - val_size train_ds, val_ds = random_split (ชุดข้อมูล [train_size, val_size]) len (train_ds), len (val_ds)

ขั้นตอนนี้เหมือนกับขั้นตอนการฝึกอบรม แต่เราต้องการแบ่งข้อมูลออกเป็นชุดฝึกอบรมและชุดตรวจสอบความถูกต้อง

(45000, 5000)
จาก torch.utils.data.dataloader นำเข้า DataLoader batch_size=64 train_dl = DataLoader(train_ds, batch_size, shuffle=True, num_workers=4, pin_memory=True) val_dl = DataLoader(val_ds, batch_size, num_memory=y=, pin_)

Torch.utils มีตัวโหลดข้อมูลที่สามารถช่วยเราโหลดข้อมูลที่จำเป็นโดยข้ามพารามิเตอร์ต่างๆ เช่น หมายเลขผู้ปฏิบัติงานหรือขนาดแบทช์

การกำหนดฟังก์ชันที่จำเป็น

@torch.no_grad() ความแม่นยำ def (เอาต์พุต, ป้ายกำกับ): _, preds = torch.max(เอาต์พุต, dim=1) return torch.tensor(torch.sum(preds == labels).item() / len(preds )) คลาส ImageClassificationBase(nn.Module): def training_step(self, batch): images, labels = batch out = self (images) # สร้างการคาดการณ์การสูญเสีย = F.cross_entropy (ออก, ป้ายกำกับ) # คำนวณการสูญเสีย accu = ความแม่นยำ (ออก ,labels) return loss,accu def validation_step(self, batch): images, labels = batch out = self(images) # สร้างการคาดการณ์การสูญเสีย = F.cross_entropy(out, labels) # คำนวณการสูญเสีย acc = ความถูกต้อง (out, labels) # คำนวณการคืนค่าความถูกต้อง {'Loss': loss.detach (), 'Accuracy': acc} def validation_epoch_end (ตัวเอง, เอาต์พุต): batch_losses = [x['Loss'] สำหรับ x ในผลลัพธ์] epoch_loss = torch.stack (batch_losses ).mean() # รวมการขาดทุน batch_accs = [x['Accuracy'] สำหรับ x ในผลลัพธ์] epoch_acc = torch.stack(batch_accs).mean() # รวมค่าความถูกต้องกลับ {'Loss': epoch_loss.item(), ' ความแม่นยำ': epoch_acc.item()} def epoch_end(ตัวเอง ยุค ผลลัพธ์): pr int("Epoch :",epoch + 1) print(f'Train Accuracy:{result["train_accuracy"]*100:.2f}% ความถูกต้องของการตรวจสอบ:{result["Accuracy"]*100:.2f}%' ) print(f'Train Loss:{result["train_loss"]:.4f} Validation Loss:{result["Loss"]:.4f}')

ดังที่เราเห็นในที่นี้ เราได้ใช้การนำคลาส ImageClassification ไปใช้งาน และต้องใช้พารามิเตอร์หนึ่งตัวคือ nn.Module ภายในคลาสนี้ เราสามารถใช้ฟังก์ชันต่างๆ หรือขั้นตอนต่างๆ เช่น การฝึกอบรม การตรวจสอบความถูกต้อง ฯลฯ ฟังก์ชันต่างๆ ที่นี่คือการใช้งานไพ ธ อนอย่างง่าย

ขั้นตอนการฝึกอบรมใช้รูปภาพและป้ายกำกับเป็นชุด เราใช้ครอสเอนโทรปีสำหรับฟังก์ชันการสูญเสียและคำนวณการสูญเสียและส่งคืนการสูญเสีย ซึ่งคล้ายกับขั้นตอนการตรวจสอบความถูกต้องตามที่เราเห็นในฟังก์ชัน ยุคสิ้นสุดรวมความสูญเสียและความแม่นยำเข้าด้วยกัน และสุดท้าย เราพิมพ์ความแม่นยำและความสูญเสีย

การใช้งานโมดูลโครงข่ายประสาทเทียม

คลาส Cifar10CnnModel(ImageClassificationBase): def __init__(self): super().__init__() self.network = nn.Sequential( nn.Conv2d(3, 32, kernel_size=3, padding=1), nn.ReLU(), nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(2, 2), # เอาต์พุต: 64 x 16 x 16 nn.BatchNorm2d(64) , nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1), nn .ReLU(), nn.MaxPool2d(2, 2), # เอาต์พุต: 128 x 8 x 8 nn.BatchNorm2d(128), nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1), nn.ReLU(), nn.MaxPool2d(2, 2), # เอาต์พุต: 256 x 4 x 4 nn.BatchNorm2d(256), nn.Flatten(), nn.Linear(256*4*4, 1024), nn.ReLU(), nn.Linear(1024, 512), nn.ReLU(), nn.Linear (512, 10)) def ไปข้างหน้า (ตัวเอง, xb): ส่งคืน self.network(xb)

นี่เป็นส่วนที่สำคัญที่สุดของการนำโครงข่ายประสาทเทียมไปใช้ เราใช้โมดูล nn ที่เรานำเข้าจากไฟฉายตลอด ดังที่เราเห็นในบรรทัดแรก Conv2d เป็นโมดูลที่ช่วยปรับใช้โครงข่ายประสาทเทียม พารามิเตอร์แรก 3 ในที่นี้แสดงว่ารูปภาพมีสีและอยู่ในรูปแบบ RGB ถ้าเป็นภาพสีเทาเราจะไป 1

32 คือขนาดของช่องสัญญาณเอาต์พุตเริ่มต้น และเมื่อเราไปที่เลเยอร์ conv2d ถัดไป เราจะมี 32 ช่องนี้เป็นช่องสัญญาณเข้า และ 64 เป็นช่องสัญญาณออก

พารามิเตอร์ที่ 3 ในบรรทัดแรกเรียกว่าขนาดเคอร์เนลและช่วยให้เราดูแลตัวกรองที่ใช้ การดำเนินการแพดดิ้งเป็นพารามิเตอร์สุดท้าย

การดำเนินการ convolution เชื่อมต่อกับเลเยอร์การเปิดใช้งานและ Relu ที่นี่ หลังจากสองชั้น Conv2d เรามีการดำเนินการรวมค่าสูงสุดที่ขนาด 2 * 2 ค่าที่ออกมาจากค่านี้จะถูกปรับให้เป็นมาตรฐานแบบกลุ่มเพื่อความเสถียรและเพื่อหลีกเลี่ยงการเปลี่ยนค่าตัวแปรร่วมภายใน การดำเนินการเหล่านี้ซ้ำแล้วซ้ำอีกโดยมีเลเยอร์มากขึ้นเพื่อให้เครือข่ายลึกขึ้นและลดขนาดลง สุดท้าย เราทำให้เลเยอร์เรียบเพื่อให้เราสามารถสร้างเลเยอร์เชิงเส้นเพื่อจับคู่ค่าต่างๆ กับ 10 ค่า ความน่าจะเป็นของเซลล์ประสาทแต่ละเซลล์ของ 10 เซลล์ประสาทเหล่านี้จะกำหนดว่ารูปภาพใดเป็นของชั้นใด โดยพิจารณาจากความน่าจะเป็นสูงสุด

ฝึกโมเดล

@torch.no_grad() def ประเมิน (model, data_loader): model.eval() outputs = [model.validation_step(batch) for batch in data_loader] return model.validation_epoch_end(outputs) def fit(model, train_loader, val_loader, epochs =10,learning_rate=0.001): best_valid = ไม่มีประวัติ = [] เครื่องมือเพิ่มประสิทธิภาพ = torch.optim.Adam(model.parameters(), learning_rate,weight_decay=0.0005) สำหรับยุคในช่วง (epochs): # Training Phase model.train ( ) train_losses = [] train_accuracy = [] สำหรับแบทช์ใน tqdm(train_loader): loss,accu = model.training_step(batch) train_losses.append(loss) train_accuracy.append(accu) loss.backward() เครื่องมือเพิ่มประสิทธิภาพขั้นตอน () .zero_grad () # ผลลัพธ์ของขั้นตอนการตรวจสอบ = ประเมิน (แบบจำลอง val_loader) ผลลัพธ์ ['train_loss'] = torch.stack (train_losses).mean ().item () ผลลัพธ์['train_accuracy'] = torch.stack (train_accuracy) ค่าเฉลี่ย ().item() model.epoch_end(ยุค, ผลลัพธ์) if(best_valid == None หรือ best_valid
ประวัติ = พอดี (รุ่น, train_dl, val_dl)

นี่เป็นขั้นตอนพื้นฐานในการฝึกโมเดลของเราเพื่อให้ได้ผลลัพธ์ที่ต้องการ ฟังก์ชันพอดีที่นี่จะพอดีกับข้อมูลรถไฟและ Val กับแบบจำลองที่เราสร้างขึ้น ฟังก์ชัน fit เริ่มต้นรายการที่เรียกว่า history ซึ่งดูแลข้อมูลการวนซ้ำของทุกยุคสมัย เราเรียกใช้ for loop เพื่อให้เราสามารถวนซ้ำในแต่ละยุคได้ สำหรับแต่ละชุดงาน เราตรวจสอบให้แน่ใจว่าเราแสดงความคืบหน้าโดยใช้ tqdm เราเรียกขั้นตอนการฝึกอบรมที่เราดำเนินการมาก่อนและคำนวณความแม่นยำและความสูญเสีย การเผยแพร่ย้อนหลังและเรียกใช้เครื่องมือเพิ่มประสิทธิภาพซึ่งเรากำหนดไว้ก่อนหน้านี้ เมื่อเราทำเช่นนี้ เราจะติดตามรายการของเราและฟังก์ชันต่างๆ ช่วยให้เราพิมพ์รายละเอียดและความคืบหน้าได้

ในทางกลับกัน ฟังก์ชันประเมินจะใช้ฟังก์ชัน eval และสำหรับแต่ละขั้นตอน เราจะนำแบตช์ที่โหลดมาจากตัวโหลดข้อมูล และคำนวณผลลัพธ์ ค่านั้นจะถูกส่งต่อไปยังช่วงสิ้นสุดการตรวจสอบที่เรากำหนดไว้ก่อนหน้านี้ และค่าที่เกี่ยวข้องจะถูกส่งคืน

พล็อตผลลัพธ์

ในขั้นตอนนี้ เราจะเห็นภาพความถูกต้องเทียบกับแต่ละยุค เราสามารถสังเกตได้ว่าเมื่อยุคนั้นเพิ่มความแม่นยำของระบบเพิ่มขึ้นเรื่อยๆ และการสูญเสียก็ลดลงเช่นเดียวกัน เส้นสีแดงแสดงความคืบหน้าของข้อมูลการฝึก และสีน้ำเงินสำหรับการตรวจสอบ เราจะเห็นได้ว่าผลลัพธ์ของเรามีการปรับมากเกินไปเนื่องจากข้อมูลการฝึกอบรมค่อนข้างมีประสิทธิภาพเหนือกว่าผลการตรวจสอบความถูกต้องและในทำนองเดียวกันในกรณีที่สูญเสีย หลังจากผ่านไป 10 ยุค ข้อมูลรถไฟดูเหมือนจะข้ามความแม่นยำ 90% แต่สูญเสียไปประมาณ 0.5 ข้อมูลการทดสอบมาประมาณ 81% และการสูญเสียใกล้ 0.2

def plot_accuracies (ประวัติ): Validation_accuracies = [x['Accuracy'] สำหรับ x ในประวัติศาสตร์] Training_Accuracies = [x['train_accuracy'] สำหรับ x ในประวัติศาสตร์] plt.plot(Training_Accuracys, '-rx') plt.plot(Validation_accuracies) , '-bx') plt.xlabel('epoch') plt.ylabel('ความถูกต้อง') plt.legend(['Training', 'Validation']) plt.title('ความแม่นยำเทียบกับจำนวนยุค') ; plot_accuracies(ประวัติ)
แปลงความแม่นยำ
def plot_losses (ประวัติ): train_losses = [x.get('train_loss') สำหรับ x ในประวัติศาสตร์] val_losses = [x['Loss'] สำหรับ x ในประวัติศาสตร์] plt.plot(train_losses, '-bx') plt.plot (val_losses, '-rx') plt.xlabel('epoch') plt.ylabel('loss') plt.legend(['Training', 'Validation']) plt.title('การสูญเสียเทียบกับจำนวนยุค '); plot_losses(ประวัติ)

test_dataset = ImageFolder(data_dir+'/test', transform=ToTensor()) test_loader = DeviceDataLoader(DataLoader(test_dataset, batch_size), device) ผล = ประเมิน (final_model, test_loader) พิมพ์ (f'Test Accuracy:{result["Accuracy" ]*100:.2f}%')
ทดสอบความถูกต้อง:81.07%

เราจะเห็นได้ว่าเราจบลงด้วยความแม่นยำ 81.07%

สรุป:

ภาพ:https://unsplash.com/photos/5L0R8ZqPZHk

เกี่ยวกับฉัน: ฉันเป็นนักศึกษาวิจัยที่สนใจในสาขาการเรียนรู้เชิงลึกและการประมวลผลภาษาธรรมชาติ และกำลังศึกษาระดับบัณฑิตศึกษาด้านปัญญาประดิษฐ์

แหล่งที่มาของภาพ

  1. Image 1: https://becominghuman.ai/cifar-10-image-classification-fd2ace47c5e8
  2. ภาพที่ 2: https://www.analyticsvidhya.com/blog/2021/05/convolutional-neural-networks-cnn/

รู้สึกอิสระที่จะเชื่อมต่อกับฉันใน:

  1.  ลิงก์ใน: https://www.linkedin.com/in/siddharth-m-426a9614a/
  2.  Github: https://github.com/Siddharth1698

สื่อที่แสดงในบทความนี้ไม่ใช่ของ Analytics Vidhya และใช้ดุลยพินิจของผู้เขียน

ที่มา: https://www.analyticsvidhya.com/blog/2021/09/convolutional-neural-network-pytorch-implementation-on-cifar10-dataset/

ประทับเวลา:

เพิ่มเติมจาก การวิเคราะห์ วิทยา