升级JDK8的坑----base64

数据加解密时Base64异常:Illegal base64 character 3a 解决办法 去掉“data:image/jpeg;base64,”即可。工具类对中文进行处理时出现异常,在数据加解密场景中经常使用。 阅读详情
AI摘要

探讨了Java 7和Java 8中Base64编码的差异,揭示了编码结果包含换行符的问题及其解决方法。

概述

Base64是一种字符串编码格式,采用了A-Z,a-z,0-9,“+”和“/”这64个字符来编码原始字符(还有垫字符“=”)。一个字符本身是一个字节,也就是8位,而base64编码后的一个字符只能表示6位的信息。也就是原始字符串中的3字节的信息编码会变成4字节的信息。Base64的主要作用是满足MIME的传输需求。
在Java8中Base64编码已经成为Java类库的标准,且内置了Base64编码的编码器和解码器。

问题

偶然发现使用jdk8内置的Base64解码器进行解析的时候,会抛出java.lang.IllegalArgumentException: Illegal base64 character a异常。
这非常奇怪,因为原文是使用jdk7里面的编码器进行编码的,理论上不至于发生这种不兼容的状况。

测试程序

还是来写程序测试一下问题到底在哪里。

测试程序使用了一个比较长的原文,主要是这个问题在原文较长的时候才会出现,如果原文较短(字节长度不超过57),那么不会有这个问题。

1 使用jdk7进行编码:

import sun.misc.BASE64Encoder;
public class TestBase64JDK7 {
    private static final String TEST_STRING = "0123456789,0123456789,0123456789,0123456789,0123456789,0123456789,0123456789";
    public static void main(String[] args) {
        BASE64Encoder base64Encoder = new BASE64Encoder();
        String base64Result = base64Encoder.encode(TEST_STRING.getBytes());
        System.out.println(base64Result);
    }
}

2 jdk7编码结果:

MDEyMzQ1Njc4Oe+8jDAxMjM0NTY3ODnvvIwwMTIzNDU2Nzg577yMMDEyMzQ1Njc4Oe+8jDAxMjM0
NTY3ODnvvIwwMTIzNDU2Nzg577yMMDEyMzQ1Njc4OQ==

3 使用jdk8对上面的编码结果进行解码:

import java.util.Base64;
public class TestBase64JDK8 {
    public static void main(String[] args) {
        String base64Result = "MDEyMzQ1Njc4Oe+8jDAxMjM0NTY3ODnvvIwwMTIzNDU2Nzg577yMMDEyMzQ1Njc4Oe+8jDAxMjM0\n" +
                "NTY3ODnvvIwwMTIzNDU2Nzg577yMMDEyMzQ1Njc4OQ==";
        Base64.getDecoder().decode(base64Result);
    }
}

4 结果就如最开始描述的那样,会抛出异常:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character a
    at java.util.Base64$Decoder.decode0(Base64.java:714)
    at java.util.Base64$Decoder.decode(Base64.java:526)
    at java.util.Base64$Decoder.decode(Base64.java:549)
    at com.francis.TestBase64JDK8.main(TestBase64JDK8.java:14)

难道说jdk7和jdk8在base64的处理上有什么不一样???

5 继续来看一下jdk8对原文的编码:

import java.util.Base64;
public class TestBase64JDK8 {
    private static final String TEST_STRING = "0123456789,0123456789,0123456789,0123456789,0123456789,0123456789,0123456789";
    public static void main(String[] args) {
        String base64Result = Base64.getEncoder().encodeToString(TEST_STRING.getBytes());
        System.out.println(base64Result);
    }
}

6 jdk8编码结果:

MDEyMzQ1Njc4Oe+8jDAxMjM0NTY3ODnvvIwwMTIzNDU2Nzg577yMMDEyMzQ1Njc4Oe+8jDAxMjM0NTY3ODnvvIwwMTIzNDU2Nzg577yMMDEyMzQ1Njc4OQ==

至此针对比较长的原文进行base64编码可以得到如下结论:

  • jdk7的编码结果包含换行;
  • jdk8的编码结果不包含换行;
  • jdk8无法解码包含换行的编码结果;

jdk8的编码结果使用jdk7进行解码,没有任何问题,不再演示。

现在问题原因基本清楚了,是由于jdk7的编码结果包含换行,导致jdk8解码的时候抛出异常。
但是为什么会有这种差异呢?难道使用的base64的标准还不一样?

问题排查

继续排查问题,先从类注释入手,看看是不是理解有误。

1 先来看看jdk8中的Base64类注释,这里只列出一些关键内容:

/**
 * This class consists exclusively of static methods for obtaining
 * encoders and decoders for the Base64 encoding scheme. The
 * implementation of this class supports the following types of Base64
 * as specified in
 * <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a> and
 * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
 *
 * <ul>
 * <li><a name="basic"><b>Basic</b></a>
 * <p> Uses "The Base64 Alphabet" as specified in Table 1 of
 *     RFC 4648 and RFC 2045 for encoding and decoding operation.
 *     The encoder does not add any line feed (line separator)
 *     character. The decoder rejects data that contains characters
 *     outside the base64 alphabet.</p></li>
 ...
 * @author  Xueming Shen
 * @since   1.8
 */

大意是说:

这个类包含了base64编码格式的编码方法和解码方法,而且实现是按照rfc4648和rfc2045两个协议来实现的。
编码和解码操作是照着两个协议中的'Table 1'中指定的'The Base64 Alphabet'来的。编码器不会添加任何换行符,解码器只会处理'The Base64 Alphabet'范围内的数据,如果不在这个范围内,解码器会拒绝处理。

看到这里就可以理解为什么jdk8的编码结果不包含换行了。
​

另外,基本上可以猜到为什么jdk8无法解码jdk7的编码结果了(换行符应该不在The base64 alphabet当中)。

2 先来看一眼两个标准中的the base64 alphabet(两个标准中的这个表是一样的):

                         Table 1: The Base 64 Alphabet
        Value Encoding  Value Encoding  Value Encoding  Value Encoding
            0 A            17 R            34 i            51 z
            1 B            18 S            35 j            52 0
            2 C            19 T            36 k            53 1
            3 D            20 U            37 l            54 2
            4 E            21 V            38 m            55 3
            5 F            22 W            39 n            56 4
            6 G            23 X            40 o            57 5
            7 H            24 Y            41 p            58 6
            8 I            25 Z            42 q            59 7
            9 J            26 a            43 r            60 8
           10 K            27 b            44 s            61 9
           11 L            28 c            45 t            62 +
           12 M            29 d            46 u            63 /
           13 N            30 e            47 v
           14 O            31 f            48 w         (pad) =
           15 P            32 g            49 x
           16 Q            33 h            50 y

并不包含换行符,这就可以解释为什么jdk8无法解码包含换行的编码结果。

3 再来看一下jdk7中sun.misc.BASE64Encoder的类注释:

   This class implements a BASE64 Character encoder as specified in RFC1521. 
   This RFC is part of the MIME specification as published by the Internet Engineering Task Force (IETF). 
   Unlike some other encoding schemes there is nothing in this encoding that indicates where a buffer starts or ends. 
   This means that the encoded text will simply start with the first line of encoded text and end with the last line of encoded text.

这个实现是按照RFC1521来的,类注释中并没有关于编码或者解码约束的说明。

4 那继续看一下rfc1521的关键部分(链接:https://tools.ietf.org/html/rfc1521)。

在5.2. Base64 Content-Transfer-Encoding章节有如下内容:

   The output stream (encoded bytes) must be represented in lines of no
      more than 76 characters each.  All line breaks or other characters
      not found in Table 1 must be ignored by decoding software.  In base64
      data, characters other than those in Table 1, line breaks, and other
      white space probably indicate a transmission error, about which a
      warning message or even a message rejection might be appropriate
      under some circumstances.

这里明确规定了:

  • 编码结果的每一行不能超过76个字符;
  • 解码的字符必须在:Tbale 1(也就是之前提到的the base64 alphabet)、换行符和空白符这个范围内;

这就是为什么jdk7的编码结果包含换行。
这样根据类注释和rfc协议内容,就可以解释上面通过测试代码得到的结论,也就可以理解为什么会产生这个问题。

‘sun’开头的包并不属于java规范,是sun公司的实现,所以jdk7中的这种base64编码方式并不是java的规范。

解决办法

那么,怎么解决这个问题呢:
1. 使用apache common包中的org.apache.commons.codec.binary.Base64类进行编码和解码;
2. 编码之后或解码之前去除换行符;
3. 编码和解码使用相同的jdk版本;

其他Base64库

看看其他类库是怎么处理base64的。
1. Apache Common

Apache Common中的org.apache.commons.codec.binary.Base64类是基于rfc2045实现的,根据类注释可以了解到此实现解码时忽略了所有不在the base64 alphabet范围内的字符,所以该实现可以处理包含换行符的base64编码结果。
同时该类的编码方法提供了参数,用于指定编码结果长度在超过76个字符的时候是否添加换行,默认不换行。

  1. Spring Core

Spring Core提供了Base64Utils类,该类只是一个工具类,并没有实现任何协议。

  • 优先使用java8中的java.util.Base64类进行编码和解码;
  • 如果java.util.Base64不存在,则会使用org.apache.commons.codec.binary.Base64;
  • 如果都不存在,则会报错

协议简述

通过上面的排查步骤可以看到,rfc1521、rfc2045和rfc4648中关于base64的部分似乎不太一样,接下来分别简单看一下这三个协议是如何规范base64编码的换行的。

  1. rfc1521(链接:https://tools.ietf.org/html/rfc1521)
    该协议是关于MIME的,Base64是MIME支持的一种编码类型。关键内容5.2. Base64 Content-Transfer-Encoding章节已经在上文中简单阐述过了,主要是规定了:编码结果每行长度和解码字符的范围。
    该协议已经被淘汰。
    jdk7基于该协议实现base64,所以编码结果会包含换行符。

    MIME:Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型。是一个互联网标准,最早用于电子邮件系统,后来被应用到浏览器。服务器会将它们发送的多媒体数据的类型告诉浏览器,而通知手段就是说明该多媒体数据的MIME类型。

  2. rfc2045(链接:https://tools.ietf.org/html/rfc2045)

    该协议同样是关于MIME的,是rfc1521的更新版本,关键内容6.8. Base64 Content-Transfer-Encoding章节,其中关于编码结果长度和解码字符范围的规定与rfc1521并没有什么差别。

  3. rfc4648

    该协议是关于base16、base32和base64编码的。关于编码结果每行长度的说明在3.1. Line Feeds in Encoded Data章节:

   MIME is often used as a reference for base 64 encoding.  However,
      MIME does not define "base 64" per se, but rather a "base 64 Content-
      Transfer-Encoding" for use within MIME.  As such, MIME enforces a
      limit on line length of base 64-encoded data to 76 characters.  MIME
      inherits the encoding from Privacy Enhanced Mail (PEM) [3], stating
      that it is "virtually identical"; however, PEM uses a line length of
      64 characters.  The MIME and PEM limits are both due to limits within
      SMTP.

   Implementations MUST NOT add line feeds to base-encoded data unless
      the specification referring to this document explicitly directs base
      encoders to add line feeds after a specific number of characters.

大意是:

   MIME协议通常作为base64协议的引用。但是MIME协议并没有定义'base64',而是定义了'base64 内容传输编码'。因此MIME将base64编码的数据的长度限制为76个字符。
   ...
   MIME和PEM关于长度的限制都是用于SMTP的。
   该协议的实现在编码结果中不能添加换行符,除非引用了该文档的实现中,明确说明在特定长度之后添加换行符。

jdk8的Base64类是基于rfc2045和rfc4648实现的,根据上文列出的协议内容可以确定,该类的编码结果不会包含换行符,而且在类的注释中明确说明了不会添加换行符。

以上!

Base64解码遇到java.lang.IllegalArgumentException: Illegal base64 character d 文章目录前言一、问题描述二、解决方法三、问题原因总结 前言 在实现了将文件通过Base64的方式加密存储到数据库中并且读取到相应的文件时,在通过Base64的解密方法进行解密时,出现了不应该出现的错误,将解决问题的过程在这里进行记录和总结 提示:以下是本篇文章正文内容,下面案例可供参考 一、问题描述 在这里进行解密时报了说d是Base64的非法字符的问题,但是在之前测试加密和解密时都没有报出这样的问题,因此在想出现问题的原因一定不是因为d是非法字符 二、解决方法 解决方法相对简单,只是将调用Base 阅读详情

相关推荐

【JDK 11】【JDK 8】项目 jdk 版本升级,修改方案与实践

本篇文章介绍了, jdk8 升级 jdk11 的一些注意问题。主要围绕-.sh 脚本启动无法启动问题javafx.util.Pair 替换sun.misc.BASE64Decoder 替换... (后续碰到会持续更新)(主要要点:)

BASK2311的博客 1684

base64解码报错Illegal base64 character

base64解码报错Illegal base64 character

qq_42338293的博客 1万+

sun.misc.BASE64Encoder.jar包

安装了JDK 9以上版本,发现sun.misc.Base64Encoder和sun.misc.Base64Decoder无法使用。找不到导入的包此时将下面的包导入libs中就可以了

【sun.misc.BASE64Encoder报错】sun.misc.BASE64Encoder报错的三种解决方法_Eclipse

问题描述 sun.misc.BASE64Encoder在eclipse中使用报错。 原因分析: sun.misc.BASE64Encoder等类不属于JDK标准库范畴,但在JDK中包含了该类,可以直接使用。但是在eclipse中直接使用却报错。在jdk1.9中就不存在了,但新版Eclipse(本人2022.2版)本身要求的jre较高,但项目使用的1.8版本,所以修改eclipse.ini会使软件打不开,但用它本身的就会版本比较高。 解决方案: 提示:本人使用网络上普遍的添加access/**的方法(即解

qq_41670382的博客 1万+

ZYNQ:【1】深入理解PS端的TTC定时器(Part1:原理+官方案例讲解)

基于UG585详细讲解其中TTC的原理和使用案例。

Alex的技术博客 7886

【BLE系列-第六篇】GATT解析:属性、特征、描述符的逻辑关系

本文系统介绍了BLE协议中的ATT和GATT机制。ATT以"属性"为基本数据单元,包含UUID、Handle、权限和Value四个要素。GATT则在ATT基础上构建了服务、特征和描述符的层次结构:服务(UUID:0x2800/0x2801)通过声明属性标识,特征声明(UUID:0x2803)指向特征值(UUID:0x2Axx或自定义),描述符(UUID:0x2900~0x290F)提供附加信息。GATT复用ATT发现机制,通过定义特定UUID语义实现服务发现和特征管理。这种设计使BLE设

qq_43399763的博客 1929

升级JDK8的坑--base64

概述 Base64是一种字符串编码格式,采用了A-Z,a-z,0-9,“+”和“/”这64个字符来编码原始字符(还有垫字符“=”)。一个字符本身是一个字节,也就是8位,而base64编码后的一个字符只能表示6位的信息。也就是原始字符串中的3字节的信息编码会变成4字节的信息。Base64的主要作用是满足MIME的传输需求。 在Java8中Base64编码已经成为Java类库的标准,且内置了Base64编码的编码器和解码器。 问题 偶然发现使用jdk8内置的Base64解码器进行解析的时候,会抛出java.l

lgxzzz的博客 1365

VSCode里玩转AvaloniaUI:手把手教你搭建跨平台桌面应用开发环境(附.NET 7配置避坑)

本文详细介绍了如何在VSCode中搭建AvaloniaUI跨平台桌面应用开发环境,包括.NET 7配置避坑指南。从环境准备、项目创建到调试优化,手把手教你利用VSCode和Avalonia实现高效开发,特别解决了.NET 7依赖等常见问题,助力开发者快速上手跨平台应用开发。

weixin_28826545的博客 576

解决 java.security.InvalidKeyException: Illegal key size 的完整排查指南

Java 开发者在使用 AES-256 等高强度加密算法时,偶尔会遇到 java.security.InvalidKeyException: Illegal key size 异常,尤其是在本地环境正常、服务器却抛错的情况下,往往让人摸不着头脑。这个问题的根源在于 JCE(Java Cryptography Extension)框架对密钥长度的限制,而 JDK 版本、策略文件和配置项都会影响这一限制。理解 JCE 的原理,掌握不同 JDK 版本的解决方案,是高效排错的关键。从查询当前环境的密钥长度限制、调整

weixin_29315569的博客 312

Abaqus子程序开发避坑指南:从UMESHMOTION到齿轮磨损分析实战

本文深入探讨Abaqus子程序开发中的关键技术与避坑指南,重点解析UMESHMOTION在齿轮磨损分析中的实战应用。从开发环境搭建、调试框架构建到性能优化和大规模计算,提供系统化的解决方案。通过真实案例展示如何避免内存泄漏、网格畸变等常见问题,并介绍数据驱动的磨损预测等前沿技术,帮助工程师提升仿真精度与效率。

weixin_30892037的博客 87

Codesys电子凸轮Cam表实战:从可视化配置到程序化构建

本文详细介绍了Codesys电子凸轮Cam表的实战应用,从可视化配置到程序化构建的全过程。通过包装机和印刷机案例,解析Cam表的基础设置、调试技巧及动态构建方法,帮助工程师快速掌握电子凸轮技术,提升运动控制精度和效率。

weixin_29309785的博客 298

jdk8升级JDK17避坑指南(适用于SpringBoot2.3---SpringBoot2.7升级)

随着SpringBoot2.7的发布,需要jdk8,兼容jdk21。Springboot3.X发布,最低需要jdk17。升级jdk17是大势所趋。

dazer的专栏 1万+

水与光的奇妙“切割之舞”:水导激光切割技术探秘

水导激光切割技术的诞生,是材料加工领域不断追求高精度、高质量加工的成果。传统激光切割技术在加工过程中,材料会因瞬间高温而产生热变形、热影响区大以及切割面粗糙等问题,这些弊端在对一些高精度、热敏性材料的加工中尤为突出 ,迫切需要一种新的技术来克服这些难题。水导激光切割技术的起源可以追溯到 20 世纪 80 年代。1986 年,德国公司 Aesculap-Werke AG 首次提出了将水流引入激光切割过程的创新想法,并制造出首代水导激光设备。不过,当时的技术尚处于雏形阶段,仅仅是在光纤出口添加了一小柱水流,激光

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 1673

jdk1.8 升级到 jdk11 遇到的一些坑

jdk1.8 升级到 jdk11 遇到的一些坑

5856

【深度学习新浪潮】算力上太空:NVIDIA Space-1 Vera Rubin Module 深度技术解析

NVIDIA Space-1 Vera Rubin Module 不只是一款芯片模组,它是天地一体化 AI 的基础设施底座。它用成熟的 GPU 架构 + 航天级加固,把地面 AI 生态直接平移到太空。下一个 AI 创新战场,不在云端,而在轨道。在轨 LLM星上多模态实时处理卫星自主组网与分布式推理太空算力成为云计算的一级节点参考资料NVIDIA 官方博客:NVIDIA 推出太空计算,将 AI 送入太空轨道GTC 2026 黄仁勋主题演讲。

专注:太空算力、AI infra、异构调度、大模型成本工程 1124

[毕设项目-MCP+ENSP]一句话搞定ENSP自动化:MCP + LLM实战(架构图、工具清单、踩坑全解)

用 MCP + LLM 把“人话”变成对华为 ENSP 的安全自动化操作,三款工具覆盖配置/查询/落盘,配套架构、实战与排坑清单。

逐梦苍穹的博客 2537

JDK从8升级到21的问题集

第一步:在本地进行编译,提前识别出语法错误、版本冲突及不兼容问题。主要有以下几种场景:Base64:参照【Base64编解码改造】升级版本jsr250、jaxb-runtime、jakarta.annotation-api:参照【注解包冲突典型案例】升级版本升级版本升级版本。

京东科技开发者 1546

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

JDK8升级到JDK11后Cannot resolve symbol ‘BASE64Encoder‘

JDK8升级到JDK11后Cannot resolve symbol ‘BASE64Encoder’

随风飘絮 1919

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

关于jdk版本BASE64Encoder报错

BASE64Encoder是jdk8之前自带的方法, 如果jdk版本高于jdk8的时候,可以选择引入base64的包, 将原来 BASE64Encoder encoder = new BASE64Encoder(); String base64Str = encoder.encode(data); 换成base64的 import org.apache.commons.codec.binary.Base64; return Base64.encodeBase64String(data); 另一个BASE

qq_45651172的博客 3750

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

ideajdk升级_JDK8升级至JDK11步骤及要点

项目环境描述:名称升级前版本升级后版本JDKJDK 8JDK 11Spring Boot2.1.02.1.0Spring CloudGreenwichGreenwichEclipseMars.2 Release (4.5.2)2019-09 R (4.13.0)一、了解JDK111、版本说明美国当地时间2018年9月25日,Oracle 官方宣布 Java 11 (18.9 LTS) 正式发布,可...

weixin_36269334的博客 2553

springboot 项目 从jdk 8 升级到jdk21 会面临哪些问题

主要的风险点:spring boot 需要升级到,大版的升级就涉及到很多中间件需要跟着升级,其次就是一些API可能被移除了,这块编译就阶段就能解决。还有就是我们maven版本和编译插件需要升级。

stone_tmp的博客 1176

「是时候升级java11了」 jdk8升级至dk11踩坑记

专栏目录 是时候升级java11了-01-jdk11优势和jdk选择 是时候升级java11了-02-升级jdk11踩坑记 是时候升级java11了-03虚拟机Jvm参数设置 是时候升级java11了-04微服务内http2通信之http2 Clear Text(h2c) 是时候升级java11了-05微服务内h2c通信的阻碍和问题解决 前言 紧接上文,下面笔者来列举我们在升级到 Java...

冷冷的博客 2737

JDK从1.8升级到9.0.1后sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用

描述 最近研究把项目的JDK升级从1.8升级到9.0.1,在eclipse上配置好JDK为9后,发现项目有错,查看发现sun.misc.BASE64Decoder和sun.misc.BASE64Encoder不可用。 原因分析 参看官网,发现JDK中的lib\tools.jar和JRE中的lib\rt.jar已从Java SE 9中删除。这些JAR中可用的类和资源现在以文件中的内部格式存储在...

码海淹没的小强的博客 712

SpringBoot2.7升级项目到Springboot3.1踩坑指南(jdk17/jdk21)

升级SpringBoot2.7到SpringBoot3

dazer的专栏 8540
上一篇: Kibana4动态指定index pattern
下一篇: Prometheus的step、increase解释
java_4_ever
博客等级 码龄16年 8粉丝 29原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值