python3 读取0x00_Python3读取深度学习CIFAR-10数据集出现的若干问题解决

在尝试使用Python3读取CIFAR-10数据集时遇到了'gbk'编码错误和内存错误。通过将文件打开模式改为'rb'并设置`pickle.load`的encoding参数为'latin1'解决了编码问题。内存问题通过限制加载批次数量得到缓解。
摘要由CSDN通过智能技术生成

今天在看网上的视频学习深度学习的时候,用到了CIFAR-10数据集。当我兴高采烈的运行代码时,却发现了一些错误:

# -*- coding: utf-8 -*-

import pickle as p

import numpy as np

import os

def load_CIFAR_batch(filename):

""" 载入cifar数据集的一个batch """

with open(filename, 'r') as f:

datadict = p.load(f)

X = datadict['data']

Y = datadict['labels']

X = X.reshape(10000, 3, 32, 32).transpose(0, 2, 3, 1).astype("float")

Y = np.array(Y)

return X, Y

def load_CIFAR10(ROOT):

""" 载入cifar全部数据 """

xs = []

ys = []

for b in range(1, 6):

f = os.path.join(ROOT, 'data_batch_%d' % (b,))

X, Y = load_CIFAR_batch(f)

xs.append(X)

ys.append(Y)

Xtr = np.concatenate(xs)

Ytr = np.concatenate(ys)

del X, Y

Xte, Yte = load_CIFAR_batch(os.path.join(ROOT, 'test_batch'))

return Xtr, Ytr, Xte, Yte

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

错误代码如下:

'gbk' codec can't decode byte 0x80 in position 0: illegal multibyte sequence

1

于是乎开始各种搜索问题,问大佬,网上的答案都是类似:

然而并没有解决问题!还是错误的!(我大概搜索了一下午吧,都是上面的答案)

哇,就当我很绝望的时候,我终于发现了一个新奇的答案,抱着试一试的态度,尝试了一下:

def load_CIFAR_batch(filename):

""" 载入cifar数据集的一个batch """

with open(filename, 'rb') as f:

datadict = p.load(f, encoding='latin1')

X = datadict['data']

Y = datadict['labels']

X = X.reshape(10000, 3, 32, 32).transpose(0, 2, 3, 1).astype("float")

Y = np.array(Y)

return X, Y

1

2

3

4

5

6

7

8

9

10

竟然成功了,这里没有报错了!欣喜之余,我就很好奇,encoding=’latin1’到底是啥玩意呢,以前没有见过啊?于是,我搜索了一下,了解到:

Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。

因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个特性。ASCII编码是一个7位的容器,ISO-8859-1编码是一个8位的容器。

还没等我高兴起来,运行后,又发现了一个问题:

memory error

1

什么鬼?内存错误!哇,原来是数据大小的问题。

X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float")

1

这告诉我们每批数据都是10000 * 3 * 32 * 32,相当于超过3000万个浮点数。 float数据类型实际上与float64相同,意味着每个数字大小占8个字节。这意味着每个批次占用至少240 MB。你加载6这些(5训练+ 1测试)在总产量接近1.4 GB的数据。

for b in range(1,2):

f = os.path.join(ROOT, 'data_batch_%d' % (b,))

X, Y = load_CIFAR_batch(f)

xs.append(X)

ys.append(Y)

1

2

3

4

5

所以如有可能,如上代码所示只能一次运行一批。

到此为止,错误基本搞定,下面贴出正确代码:

# -*- coding: utf-8 -*-

import pickle as p

import numpy as np

import os

def load_CIFAR_batch(filename):

""" 载入cifar数据集的一个batch """

with open(filename, 'rb') as f:

datadict = p.load(f, encoding='latin1')

X = datadict['data']

Y = datadict['labels']

X = X.reshape(10000, 3, 32, 32).transpose(0, 2, 3, 1).astype("float")

Y = np.array(Y)

return X, Y

def load_CIFAR10(ROOT):

""" 载入cifar全部数据 """

xs = []

ys = []

for b in range(1, 2):

f = os.path.join(ROOT, 'data_batch_%d' % (b,))

X, Y = load_CIFAR_batch(f)

xs.append(X) #将所有batch整合起来

ys.append(Y)

Xtr = np.concatenate(xs) #使变成行向量,最终Xtr的尺寸为(50000,32,32,3)

Ytr = np.concatenate(ys)

del X, Y

Xte, Yte = load_CIFAR_batch(os.path.join(ROOT, 'test_batch'))

return Xtr, Ytr, Xte, Yte

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

import numpy as np

from julyedu.data_utils import load_CIFAR10

import matplotlib.pyplot as plt

plt.rcParams['figure.figsize'] = (10.0, 8.0)

plt.rcParams['image.interpolation'] = 'nearest'

plt.rcParams['image.cmap'] = 'gray'

# 载入CIFAR-10数据集

cifar10_dir = 'julyedu/datasets/cifar-10-batches-py'

X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)

# 看看数据集中的一些样本:每个类别展示一些

print('Training data shape: ', X_train.shape)

print('Training labels shape: ', y_train.shape)

print('Test data shape: ', X_test.shape)

print('Test labels shape: ', y_test.shape)

顺便看一下CIFAR-10数据组成:

使用ft4222python的spiMaster_MultiReadWrite函数可以实现SPI总线上的多线程读写操作。要使用该函数读取寄存器0x01h的值,需要按照以下步骤进行操作: 1. 打开SPI总线,配置SPI总线的工作模式、时钟速度、数据位数等参数。 2. 构造要发送的命令字节序列,该命令字节序列包括读取寄存器0x01h的命令代码。 3. 调用spiMaster_MultiReadWrite函数发送命令字节序列并接收寄存器的值。 4. 对接收到的寄存器值进行解析和处理。 下面是一个简单的示例代码,演示如何使用spiMaster_MultiReadWrite函数读取寄存器0x01h的值: ```python import ft4222 import struct # 打开SPI总线 spi = ft4222.SPI( master=True, four_wire=False, io_protocol=ft4222.SPI_IO_PROTOCOL_SINGLE, clk_div=0, clk_polarity=0, clk_phase=0, sso_map=0x01, sso_act_level=0, txd_fifo_trigger_level=0, rxd_fifo_trigger_level=0 ) # 构造命令字节序列,读取寄存器0x01h cmd = struct.pack('>B', 0x81) # 发送命令并接收寄存器值 rxbuf = spi.spiMaster_MultiReadWrite(cmd, 1) # 解析寄存器值 reg_val = struct.unpack('>B', rxbuf)[0] # 处理寄存器值 print('Register value: 0x{:02x}'.format(reg_val)) ``` 在该示例代码,我们首先打开SPI总线,然后构造一个长度为1的命令字节序列cmd,其第一个字节0x81表示读取寄存器0x01h的命令代码。接下来,我们调用spiMaster_MultiReadWrite函数发送命令并接收寄存器的值,将接收到的1个字节存储在rxbuf。最后,我们使用struct模块解析rxbuf的寄存器值,并进行后续处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值