为啥每次我在这个特定数据集上运行 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 时我的内核都会死掉?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 LinearSVC 在这个数据集上效果这么差?

为啥 libsvm 在同一数据集上创建不同的结果

有没有办法在分区的 spark 数据集上并行运行操作?

为啥物体检测会导致找到多个物体?

为啥这个 Dijkstra 算法不适用于这个特定的输入?

大型数据集上的 R 中的矩阵数学