如何在Google Cloud Datalab中访问Cloud Bucket图像并适配Keras图像生成器?
解决Google Cloud Datalab中访问GCS图像训练自编码器的问题
我来帮你搞定这个问题!在Google Cloud Datalab里访问GCS桶的图像,不管用不用Keras的ImageDataGenerator都有可行的方案,下面给你详细说明:
方案1:挂载GCS桶到本地文件系统(适配flow_from_directory)
ImageDataGenerator.flow_from_directory需要可访问的文件系统路径,你可以用gcsfuse把GCS桶挂载到Datalab的实例中,这样就能像访问本地文件夹一样用它了:
- 首先在Datalab的代码单元格中执行挂载命令(替换成你的桶名):
!gcsfuse --implicit-dirs your-gcs-bucket-name /content/gcs-mounted-bucket
--implicit-dirs参数是为了让GCS的虚拟目录能被识别到。
- 确认挂载成功后,就可以用这个挂载路径作为
flow_from_directory的参数了。注意:flow_from_directory要求目录结构是父目录下包含子文件夹(每个子文件夹对应一个类别),对于自编码器(class_mode='input'),你可以把所有训练图像放在同一个子文件夹下(比如/content/gcs-mounted-bucket/training/images),然后指向父目录training:
from keras.preprocessing.image import ImageDataGenerator datagen = ImageDataGenerator(rescale=1./255) training_set = datagen.flow_from_directory( '/content/gcs-mounted-bucket/training', # 父目录,里面有images子文件夹 target_size=(112,112), batch_size=32, class_mode='input' ) test_set = datagen.flow_from_directory( '/content/gcs-mounted-bucket/test', target_size=(112,112), batch_size=32, class_mode='input' )
方案2:用TensorFlow原生tf.data加载(无需ImageDataGenerator)
如果不想用ImageDataGenerator,直接用tf.data更适配GCP的环境,代码也很清晰:
import tensorflow as tf # 1. 获取GCS上所有训练图像的路径(根据你的图像格式调整后缀,比如png) train_image_paths = tf.io.gfile.glob('gs://your-gcs-bucket-name/training/**/*.jpg', recursive=True) test_image_paths = tf.io.gfile.glob('gs://your-gcs-bucket-name/test/**/*.jpg', recursive=True) # 2. 定义图像预处理函数 def preprocess_image(image_path): # 读取图像文件 img_raw = tf.io.read_file(image_path) # 解码图像(JPEG格式,换成decode_png如果是PNG) img = tf.image.decode_jpeg(img_raw, channels=3) # 调整尺寸到目标大小 img = tf.image.resize(img, (112, 112)) # 归一化到[0,1]区间 img = img / 255.0 # 自编码器的输入和标签都是图像本身 return img, img # 3. 构建训练和测试数据集 training_dataset = tf.data.Dataset.from_tensor_slices(train_image_paths) training_dataset = training_dataset.map(preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) training_dataset = training_dataset.batch(32).prefetch(tf.data.AUTOTUNE) # 预取提升效率 test_dataset = tf.data.Dataset.from_tensor_slices(test_image_paths) test_dataset = test_dataset.map(preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) test_dataset = test_dataset.batch(32).prefetch(tf.data.AUTOTUNE)
之后你就可以把training_dataset和test_dataset直接传入模型的fit方法了。
方案3:用flow_from_dataframe配合GCS路径(保留ImageDataGenerator)
如果你还是想用ImageDataGenerator的增强功能,可以用flow_from_dataframe,它支持直接传入GCS的图像路径:
import pandas as pd from keras.preprocessing.image import ImageDataGenerator import tensorflow as tf # 1. 获取所有图像路径并构建DataFrame train_paths = tf.io.gfile.glob('gs://your-gcs-bucket-name/training/*.jpg') train_df = pd.DataFrame({'filename': train_paths}) test_paths = tf.io.gfile.glob('gs://your-gcs-bucket-name/test/*.jpg') test_df = pd.DataFrame({'filename': test_paths}) # 2. 用ImageDataGenerator加载数据 datagen = ImageDataGenerator(rescale=1./255) training_set = datagen.flow_from_dataframe( dataframe=train_df, x_col='filename', # 存储图像路径的列名 y_col=None, # 自编码器不需要额外标签,用class_mode='input'自动把图像作为标签 target_size=(112,112), batch_size=32, class_mode='input' ) test_set = datagen.flow_from_dataframe( dataframe=test_df, x_col='filename', y_col=None, target_size=(112,112), batch_size=32, class_mode='input' )
注意事项
- 确保Datalab的服务账号有访问目标GCS桶的权限,默认情况下Datalab实例的服务账号会有桶的访问权限,如果没有,需要在GCS桶的权限设置中给该账号添加存储对象查看者角色。
- 如果你的图像格式不是JPEG,记得把代码中的
decode_jpeg或者文件后缀改成对应的格式(比如PNG用decode_png)。
内容的提问来源于stack exchange,提问作者Gianni
相关产品推荐
相关产品推荐

