Google Drive超时引发FileNotFoundError?TensorFlow数据生成器问题咨询
首先可以明确:你的FileNotFoundError确实是Google Drive挂载超时/连接中断导致的。在Google Colab中,当你挂载Drive后,如果长时间闲置、使用多进程读取文件,或者Colab的后台连接波动,都会导致Drive的挂载会话失效——原本能访问的路径会变成无效路径,进而触发文件找不到的错误,哪怕你切换回CPU运行,只要Drive连接没恢复,错误就会持续。
下面是针对这个问题的具体修改方案,按优先级从高到低排序:
1. 优先把数据集复制到Colab本地硬盘(最稳妥的方案)
Drive的远程读取不仅容易超时,速度也远不如Colab本地存储。把数据集复制到本地后,既能彻底摆脱Drive连接的依赖,还能大幅提升训练速度(尤其GPU训练时效果更明显)。
执行以下命令复制数据(注意路径匹配你的Drive结构):
# 创建本地存储目录 !mkdir -p /content/local_car_dataset # 从Drive复制数据集到本地 !cp -r "/content/drive/MyDrive/data/2017-IWT4S-CarsReId_LP-dataset/" /content/local_car_dataset/
然后修改你的路径生成代码,改用本地路径:
X_train = [] for name in train_FileName: # 替换成本地路径 file_path = r"/content/local_car_dataset/2017-IWT4S-CarsReId_LP-dataset/" + name X_train.append(file_path)
2. 修复Drive挂载路径并重新挂载
你之前的路径用了/content/gdrive/My Drive/,注意新版Colab的Drive挂载路径是/content/drive/MyDrive/(没有空格),旧的gdrive挂载方式已经被弃用,空格也可能导致路径解析问题。
重新执行挂载命令,确保授权成功:
from google.colab import drive # 重新挂载Drive,会弹出授权链接 drive.mount('/content/drive')
然后把所有路径中的/content/gdrive/My Drive/替换成/content/drive/MyDrive/,避免路径错误。
3. 调整多进程训练的设置
当你使用use_multiprocessing=True时,子进程可能无法继承Drive的挂载会话,导致子进程里无法访问Drive文件。可以先尝试关闭多进程验证:
model.fit_generator( generator=training_generator, validation_data=validation_generator, steps_per_epoch = num_train_samples // 32, validation_steps = num_val_samples // 32, epochs = 10, # 先关闭多进程 use_multiprocessing=False, workers=1 )
如果必须用多进程,结合方案1(本地数据)是唯一可靠的方式,因为本地文件系统的访问不会受进程继承问题影响。
4. 在DataGenerator中添加异常重试机制
如果暂时不想复制数据,可以在读取文件时捕获FileNotFoundError,尝试重新挂载Drive并重试读取:
import tensorflow.keras as keras from skimage.io import imread from skimage.transform import resize import numpy as np import math from tensorflow.keras.utils import Sequence from google.colab import drive # `x_set`为图片路径列表,`y_set`为对应类别 class DataGenerator(Sequence): def __init__(self, x_set, y_set, batch_size): self.x, self.y = x_set, y_set self.batch_size = batch_size def __len__(self): return math.ceil(len(self.x) / self.batch_size) def _read_image(self, file_name): try: return resize(imread(file_name), (224, 224)) except FileNotFoundError: # 强制重新挂载Drive drive.mount('/content/drive', force_remount=True) # 重试读取 return resize(imread(file_name), (224, 224)) def __getitem__(self, idx): batch_x = self.x[idx * self.batch_size:(idx + 1) * self.batch_size] batch_y = self.y[idx * self.batch_size:(idx + 1) * self.batch_size] return np.array([self._read_image(file_name) for file_name in batch_x]), np.array(batch_y)
不过这种方式只是临时补救,稳定性远不如方案1。
内容的提问来源于stack exchange,提问作者Tobitor

