为啥每次我在这个特定数据集上运行 train-test split 时我的内核都会死掉?
Posted
技术标签:
【中文标题】为啥每次我在这个特定数据集上运行 train-test split 时我的内核都会死掉?【英文标题】:Why does my kernel die every time I run train-test split on this particular dataset?为什么每次我在这个特定数据集上运行 train-test split 时我的内核都会死掉? 【发布时间】:2021-11-22 12:11:04 【问题描述】:我之前使用过训练测试拆分,没有遇到任何问题。我的 CNN 有一个相当大的 (1GB) 数据集并尝试使用它,但我的内核每次都死机。我读到有时输入shuffle=False
会有所帮助。我试过了,但没有运气。我在下面包含了我的代码。任何帮助将不胜感激!
import pandas as pd
import os
import cv2
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from PIL import Image
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import Adam
from sklearn.metrics import accuracy_score
np.random.seed(42)
data_dir='birds/'
train_path=data_dir+'/train'
test_path=data_dir+'/test'
img_size=(100,100)
channels=3
num_categories=len(os.listdir(train_path))
#get list of each category to zip
names_of_species=[]
for i in os.listdir(train_path):
names_of_species.append(i)
#make list of numbers from 1-300:
num_list=[]
for i in range(300):
num_list.append(i)
nums_and_names=dict(zip(num_list, names_of_species))
folders=os.listdir(train_path)
import random
from matplotlib.image import imread
df=pd.read_csv(data_dir+'/Bird_Species.csv')
img_data=[]
img_labels=[]
for i in nums_and_names:
path=data_dir+'train/'+str(names_of_species[i])
images=os.listdir(path)
for img in images:
try:
image=cv2.imread(path+'/'+img)
image_fromarray=Image.fromarray(image, 'RGB')
resize_image=image_fromarray.resize((img_size))
img_data.append(np.array(resize_image))
img_labels.append(num_list[i])
except:
print("Error in "+img)
img_data=np.array(img_data)
img_labels=np.array(img_labels)
img_labels
array([210, 41, 148, ..., 15, 115, 292])
#SHUFFLE TRAINING DATA
shuffle_indices=np.arange(img_data.shape[0])
np.random.shuffle(shuffle_indices)
img_data=img_data[shuffle_indices]
img_labels=img_labels[shuffle_indices]
#Split the data
X_train, X_test, y_train, y_test=train_test_split(img_data,img_labels, test_size=0.2,random_state=42, shuffle=False)
#Resize data
X_train=X_train/255
X_val=X_val/255
【问题讨论】:
我不知道是不是内存的问题,但是,如果是这样,我建议首先仅按图像名称拆分数据。然后加载它们。我的意思是首先获取数组中的图像路径,拆分训练和测试集,然后编写一个函数来加载路径数组中的每个图像路径。我还建议使用flow_from_directory
方法,这在您的情况下更简单,您可以用更简洁的代码完成以上所有操作。
【参考方案1】:
这意味着您的 RAM 或 GPU 内存可能已用完。
要检查 Windows 打开任务管理器 (ctrl+shft+esc),转到性能运行代码,然后检查 RAM 使用情况和 GPU 内存使用情况以确定原因是否是其中任何一个。
注意:要监控 GPU 内存,您应该监控“专用 GPU 内存”,单击 GPU 时可以在左下方找到。
【讨论】:
好的,我该如何解决这个问题?目前我的计算机上没有运行其他任何东西。【参考方案2】:添加到 MK 答案,如果您的内核崩溃的原因确实是由于 RAM/GPU 限制。您可以尝试分批加载数据。与其同时拆分整个数据集,不如尝试一次拆分四分之一。
【讨论】:
【参考方案3】:请注意,拆分数据后,您基本上保留了相同数据的 2 个实例(原始 (img_data, img_labels)
和拆分形式)。如果内存不足,最好通过索引数组来管理它,您可以根据需要从该数组中隐式提取批次。
创建随机索引数组,
shuffle_indices = np.random.permutation(img_data.shape[0])
这与您的两行在一个步骤中的作用相同。
拆分对应于训练集和测试集中点的索引:
train_indices, test_indices = train_test_split(shuffle_indices, test_size=0.2,random_state=42, shuffle=False))
然后,迭代批次,
n_train = len(train_indices)
for epoch on range(n_epochs):
# further shuffle the training data for each iteration, if desired
epoch_shuffle = np.random.permutation(n_train)
for i in range(n_train, step=batch_size):
# get data batches
x_batch = img_data[train_indices[epoch_shuffle[i*batch_size : (i+1)*batch_size]]]
y_batch = img_labels[train_indices[epoch_shuffle[i*batch_size : (i+1)*batch_size]]]
# train model
...
【讨论】:
以上是关于为啥每次我在这个特定数据集上运行 train-test split 时我的内核都会死掉?的主要内容,如果未能解决你的问题,请参考以下文章