raytracinginoneweekend超详解光线追踪1-10(代码片段)

lv-anchoret lv-anchoret     2023-02-20     278

关键词:

 

《Ray Tracing in One Weekend》完结篇

最近课程上机实验,封面图渲染时间也超长,所以写东西就落下了,见谅

这篇之后,我会继续《Ray Tracing The Next Week》,还请多多关注

 

这几天我在渲染这本书的封面图,封面图还没出,不算结束,刚好安排了10节

今天呢,有两件事:

1.阐述整个工程的文件组织即内容

2.阐述封面,完结

 

 

12.1工程文件组织

试过很多方法,问过很多老师,无奈,子类继承实现的父类纯虚函数实在无法和类声明分成两个文件(即声明放于.h,其他实现放在.cpp中),室友说,纯虚函数继承实现和模板很类似

所以,我们在合适的时候使用hpp

在学习过程中,我们遇到了诸如反射、折射之类的函数,它们并不应该属于某个具体子类,或者抽象基类

所以,我把它们写在了泛型3D数学库里面了

C++泛型3D数学库是我们学光线追踪的数学专用库了吧算是

向量库

基础光学几何函数库

技术分享图片

技术分享图片

 

在回头看我们的光线追踪的项目代码

1.工程定义文件

我们之前是在ray这个最基本的类中定义了一些基本的命名,尔后,发现,所有的东西都要用ray::val_type诸如此类的代码去描述光线追踪所用到的一些普遍类型,这个非常麻烦,代码也长,后来,我们将它们移出了ray-class,放在了namespace rt中,但是,仍然放在ray文件中,这个很不合理,所以我们定义了一个RTdef.h,专门用于定义一些光线追踪的常量和命名

/// RTdef.h

// -----------------------------------------------------
// [author]        lv
// [begin ]        2019.1.1
// [brief ]        the basic concept of rt
// -----------------------------------------------------
#pragma once

#include <lvgm	ype_vec	ype_vec.h>        //https://www.cnblogs.com/lv-anchoret/p/10163085.html
#include <lvgmopticsfunc.hpp>            //https://www.cnblogs.com/lv-anchoret/p/10241904.html
#include <lvgm
andfunc.hpp>            //https://www.cnblogs.com/lv-anchoret/p/10241904.html

namespace rt

    using rtvar = lvgm::precision;

    using rtvec = lvgm::vec3<rtvar>;

    constexpr static rtvar rtInf()  return static_cast<rtvar>(0x3f3f3f3f);         //最大值

    constexpr rtvar π = 3.1415926;

 

2.光线类

/// ray.h

// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.12
// [brief ]        the ray-class for the ray-tracing project
//                from the 《ray tracing in one week》
// -----------------------------------------------------
#pragma once

#include "RTdef.h"

namespace rt


    class ray
    
    public:
        ray()
            :_a rtvec() 
            , _b rtvec() 
          

        ray(const rtvec& a, const rtvec& b)
            :_a(a)
            , _b(b)
          

        ray(const ray& r)
            :_a(r._a)
            , _b(r._b)
            

        inline rtvec origin()const  return _a; 

        inline rtvec direction()const  return _b; 

        inline rtvec go(const rtvar t)const  return _a + t * _b; 

    private:
        rtvec _a;

        rtvec _b;

    ;

 

3.相机类

 

/// camera.h
//https://www.cnblogs.com/lv-anchoret/p/10221058.html
// -----------------------------------------------------
// [author]        lv
// [begin ]        2019.1
// [brief ]        the camera-class for the ray-tracing project
//                from the 《ray tracing in one week》
// -----------------------------------------------------

#pragma once

#include "ray.h"

namespace rt


class camera
    
public:
    camera(rtvec lookfrom, rtvec lookat, rtvec vup, rtvar vfov, rtvar aspect, rtvar aperture, rtvar focus)
        :_eye(lookfrom)
        , _lens_radius(aperture / 2)
    
        rtvar theta = vfov * π / 180;
        rtvar half_height = tan(theta / 2) * focus;        //tan(theta/2) = (height/2) / 焦距
        rtvar half_width = aspect * half_height;
        _w = (lookfrom - lookat).ret_unitization();
        _u = cross(vup, _w).ret_unitization();
        _v = cross(_w, _u);

        //向量运算
        _start = _eye - half_width * _u - half_height * _v - focus * _w;//高和宽都乘了焦距,w也要乘,不然公式是错的
        _horizontal = 2 * half_width * _u;
        _vertical = 2 * half_height * _v;
    

    const ray get_ray(const rtvar u, const rtvar v)const
    
        rtvec rd = rtvec(_lens_radius * lvgm::random_unit_plane());
        rtvec offset = _u * rd.x() + _v * rd.y();
        return ray _eye + offset, _start + u*_horizontal + v*_vertical - (_eye + offset) ;
    

    const ray get_ray(const lvgm::vec2<rtvar>& para)const        return get_ray(para.u(), para.v());    

    inline const rtvec& eye()const  return _eye; 

    inline const rtvec& start()const  return _start; 

    inline const rtvec& horizontal()const  return _horizontal; 

    inline const rtvec& vertical()const  return _vertical; 

    inline const rtvec& u()const  return _u; 

    inline const rtvec& v()const  return _v; 

    inline const rtvec& w()const  return _w; 

    inline const rtvar lens_r()const  return _lens_radius; 

private:
    rtvec _u;

    rtvec _v;

    rtvec _w;

    rtvec _eye;

    rtvec _start;        //left-bottom

    rtvec _horizontal;

    rtvec _vertical;

    rtvar _lens_radius;  //the radius of lens

    ;

 

 

4.碰撞相交部分

有一个碰撞相交基类

 

/// intersect.h
//https://www.cnblogs.com/lv-anchoret/p/10190092.html
// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.12
// [brief ]        the intersect-class for the ray-tracing project
//                from the 《ray tracing in one week》
// -----------------------------------------------------
#pragma once

namespace rt

    class material;

struct hitInfo
    
    lvgm::precision _t;        //ray 中的系数t
    rtvec _p;                //相交点、撞击点
    rtvec _n;                //_p点的表面法线
    material* materialp;    //材质
    ;

class intersect
    
public:
    intersect()   

    /*
    @brief: 撞击函数,求取撞击点相关记录信息
    @param: sight->视线
    系数t的上下界->筛选撞击点
    rec->返回撞击点信息
    @retur: 是否存在合法撞击点
    */
    virtual bool hit(const ray& sight, rtvar t_min, rtvar t_max, hitInfo& rec)const = 0;

    virtual ~intersect()   
    ;

 

 

 

后面有一个子类intersections是用于处理一组碰撞相交的类,类比于容器

/// intersections.h
//    https://www.cnblogs.com/lv-anchoret/p/10190092.html

// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.12
// [brief ]        the intersections-class for the ray-tracing project
//                from the 《ray tracing in one week》
// -----------------------------------------------------
#pragma once

namespace rt


class intersections :public intersect
    
public:
    intersections()   
        
    intersections(intersect** list, size_t n) :_list(list), _size(n)   
        
    virtual bool hit(const ray& sight, rtvar t_min, rtvar t_max, hitInfo& rec)const override;

private:
    intersect** _list;

    size_t _size;
    ;


bool intersections::hit(const ray& sight, rtvar t_min, rtvar t_max, hitInfo& rec)const

    hitInfo t_rec;
    bool hitSomething = false;
    rtvar far = t_max;            //刚开始可以看到无限远
    for (int i = 0; i < _size; ++i)
    
        if (_list[i]->hit(sight, t_min, far, t_rec))
        
            hitSomething = true;
            far = t_rec._t;            //将上一次的最近撞击点作为视线可达最远处
            rec = t_rec;
        
    
    return hitSomething;



 

还有一个子类sphere是一种几何体用来做自身的碰撞检测的,之后,我们可能还会加入心形几何体类

/// sphere.h
//  https://www.cnblogs.com/lv-anchoret/p/10190092.html
// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.1.1
// [brief ]        the sphere-class for the ray-tracing project
//                from the 《ray tracing in one week》
// -----------------------------------------------------
#pragma once

namespace rt


class sphere :public intersect
    
public:
    sphere()   

        /*
        @para1: 球心坐标
        @para2: 球半径
        @para3: 材质
        */
    sphere(const rtvec& h, rtvar r, material* ma) :_heart(h), _radius(r), _materialp(ma)    

    ~sphere()  if (_materialp)    delete _materialp; 
        
    virtual bool hit(const ray& sight, rtvar t_min, rtvar t_max, hitInfo& rec)const override;

    inline const rtvar r()const             return _radius;    

    inline const rtvec& heart()const     return _heart;    

    inline rtvar& r()                     return _radius;    

    inline rtvec& heart()                 return _heart;    

private:
    rtvec _heart;

    rtvar _radius;

    material* _materialp;
    ;



bool sphere::hit(const ray& sight, rtvar t_min, rtvar t_max, hitInfo& rec)const

    rtvec trace = sight.origin() - _heart;
    rtvar a = dot(sight.direction(), sight.direction());
    rtvar b = 2.0 * dot(trace, sight.direction());
    rtvar c = dot(trace, trace) - _radius * _radius;
    rtvar delt = b*b - 4.0*a*c;
    if (delt > 0)
    
        rec.materialp = _materialp;
        rtvar x = (-b - sqrt(delt)) / (2.0*a);
        if (x < t_max && x > t_min)
        
            rec._t = x;
            rec._p = sight.go(rec._t);
            rec._n = (rec._p - _heart) / _radius;
            return true;
        
        x = (-b + sqrt(delt)) / (2.0*a);
        if (x < t_max && x > t_min)
        
            rec._t = x;
            rec._p = sight.go(x);
            rec._n = (rec._p - _heart) / _radius;
            return true;
        
    
    return false;


 

一个总文件

/// RThit.h
//    https://www.cnblogs.com/lv-anchoret/p/10190092.html

// -----------------------------------------------------
// [author]        lv
// [begin ]        2019.1
// [brief ]        some intersects
//                intersections
//                sphere
//                heart
// -----------------------------------------------------

#pragma once

#include "ray.h"
#include "intersect.h"

#include "sphere.hpp"
#include "intersections.hpp"

 

5.材质类

材质有一个基类和三个子类

/// material.h

// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.12
// [brief ]        the material-class for the ray-tracing project
//                from the 《ray tracing in one week》
// -----------------------------------------------------
#pragma once

namespace rt


//abstract basic class
class material
    
public:

    /*
    @brief: produce a scattered ray
    @param: InRay -> Incident light
            info -> the information of intersect-point(hit-point)
            attenuation -> when scattered, how much the ray should be attenuated by tis reflectance R
            scattered -> as we talk, it is a new sight; or
                         it is the scattered ray with the intersect-point
    @retur: the function calculate a scattered ray or not
    */
    virtual bool scatter(const ray& InRay, const hitInfo& info, rtvec& attenuation, ray& scattered)const = 0;

    ;

 

/// diffuse.hpp
// https://www.cnblogs.com/lv-anchoret/p/10198423.html

// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.12
// [brief ]        one of the materials
// -----------------------------------------------------

#pragma once

namespace rt

//diffuse material
class lambertian : public material
    
public:
    lambertian(const rtvec& a) :_albedo(a)   

    bool scatter(const ray& rIn, const hitInfo& info, rtvec& attenuation, ray& scattered)const override
    
        rtvec target = info._p + info._n + lvgm::random_unit_sphere();
        scattered = ray info._p, target - info._p ;
        attenuation = _albedo;
        return true;
    
protected:

    rtvec _albedo;
    ;

 

/// metal.hpp
// https://www.cnblogs.com/lv-anchoret/p/10206773.html

// -----------------------------------------------------
// [author]        lv
// [begin ]        2018.12
// [brief ]        one of the materials
// -----------------------------------------------------

#pragma once

namespace rt

//metal material
class metal :public material
    
public:

    metal(const rtvec& a, const rtvar f = 0.) :_albedo(a) 
         
        if (f < 1 && f >= 0)_fuzz = f;
        else _fuzz = 1;
        
    
    virtual bool scatter(const ray& rIn, const hitInfo& info, rtvec& attenuation, ray& scattered)const
    
        rtvec target = reflect(rIn.direction().ret_unitization(), info._n);
        scattered = ray info._p, target + _fuzz * lvgm::random_unit_sphere() ;
        attenuation = _albedo;
        return dot(scattered.direction(), info._n) != 0;
    

    inline static rtvec reflect(const rtvec& in, const rtvec& n)  return in - 2 * dot(in, n)*n; 
    
protected:

    rtvec _albedo;

    rtvar _fuzz;
    ;

 

 

/// dielectric.hpp
// https://www.cnblogs.com/lv-anchoret/p/10217719.html

// -----------------------------------------------------
// [author]        lv
// [begin ]        2019.1
// [brief ]        one of the materials
// -----------------------------------------------------
#pragma once

namespace rt

    class dielectric :public material
    
    public:
        dielectric(const rtvar RI) :_RI(RI)   

        virtual bool scatter(const ray& InRay, const hitInfo& info, rtvec& attenuation, ray& scattered)const override;

    protected:
        rtvar _RI;

        inline rtvar schlick(const rtvar cosine)const;
    ;
    


    bool dielectric::scatter(const ray& InRay, const hitInfo& info, rtvec& attenuation, ray& scattered)const
    
        rtvec outward_normal;
        rtvec refracted;
        rtvec reflected = reflect(InRay.direction(), info._n);
        rtvar eta;
        rtvar reflect_prob;
        rtvar cos;
        attenuation = rtvec(1., 1., 1.);

        if (dot(InRay.direction(), info._n) > 0)
        
            outward_normal = -info._n;
            eta = _RI;
            cos = _RI * dot(InRay.direction(), info._n) / InRay.direction().normal();
        
        else
        
            outward_normal = info._n;
            eta = 1.0 / _RI;
            cos = -dot(InRay.direction(), info._n) / InRay.direction().normal();
        

        if (refract(InRay.direction(), outward_normal, eta, refracted))
            reflect_prob = schlick(cos);    //如果有折射,计算反射系数
        else
            reflect_prob = 1.0;        //如果没有折射,那么为全反射

        if (lvgm::rand01() < reflect_prob)
            scattered = ray(info._p, reflected);
        else
            scattered = ray(info._p, refracted);

        return true;
    

    inline rtvar dielectric::schlick(const rtvar cosine)const
    
        rtvar r0 = (1. - _RI) / (1. + _RI);
        r0 *= r0;
        return r0 + (1 - r0)*pow((1 - cosine), 5);
    


 

总文件

/// RTmaterial.h

// -----------------------------------------------------
// [author]        lv
// [begin ]        2019.1
// [brief ]        some materials
//                diffuse
//                metal
//                dielectric
// -----------------------------------------------------
#pragma once

#include "ray.h"
#include "intersect.h"
#include "material.h"

#include "diffuse.hpp"
#include "metal.hpp"
#include "dielectric.hpp"

 

我们所有的文件就写完了

 

12.2封面完结

技术分享图片

这个图让我学会了分段渲染。。。

这个图非常好看,于是乎,整了一个600*400的,整整渲染了两天(....),内心是崩溃的

我试过并发编程,结果效果不好(自己也不怎么会上锁。。。)

所以,就只能单线程处理,时间超过十个小时左右吧,VS那个时间过程诊断框就坏死了。。。

有时候,不能一直渲染,这个时候,被迫结束后,只需要读取已有文件的行数,然后计算出渲染了多少个点了,然后在渲染的双重for循环中从下一个点开始渲染写入文件即可,就可以随时随地想停就停,想渲染就渲染,因为图像本事就是一个一个像素点,我们只需要24w个点的文件数据即可,你也可以并发写入多个文件,最后拼在一起

 

我们采用的相机参数是这样的

技术分享图片

据说是官方的,我也不清楚

还有一个文章写得非常好,是写相机的参数测试的,大家可以阅读一下,对相机的参数有一个更直观深入的了解

相机各个参数测试效果

 

因为这个图实在是渲染了好久,所以也没有出一些其他的效果图,可能之后会更,大家可以自己设置球体以及相机,欢迎在评论区发出你的渲染图~

 

下面是代码:

#define LOWPRECISION

#include <fstream>
#include "RTmaterial.h"
#include "RThit.h"
#include "camera.h"
#define stds std::
using namespace rt;

rtvec lerp(const ray& sight, intersect* world, int depth)

    hitInfo info;
    if (world->hit(sight, (rtvar)0.001, rtInf(), info))
    
        ray scattered;
        rtvec attenuation;
        if (depth < 50 && info.materialp->scatter(sight, info, attenuation, scattered))
            return attenuation * lerp(scattered, world, depth + 1);
        else
            return rtvec(0, 0, 0);
    
    else
    
        rtvec unit_dir = sight.direction().ret_unitization();
        rtvar t = 0.5*(unit_dir.y() + 1.);
        return (1. - t)*rtvec(1., 1., 1.) + t*rtvec(0.5, 0.7, 1.0);
    


intersect* random_sphere()

    int cnt = 500;
    intersect **list = new intersect*[cnt + 1];
    list[0] = new sphere(rtvec(0, -1000, 0), 1000, new lambertian(rtvec(0.5, 0.5, 0.5)));
    int size = 1;
    for (int a = -11; a < 11; ++a)
        for (int b = -11; b < 11; ++b)
        
            rtvar choose_mat = lvgm::rand01();
            rtvec center(a + 0.9 * lvgm::rand01(), 0.2, b + 0.9*lvgm::rand01());
            if ((center - rtvec(4, 0.2, 0)).normal()>0.9)
            
                if (choose_mat < 0.75)
                
                    list[size++] = new sphere(center, 0.2, new lambertian(rtvec(lvgm::rand01()*lvgm::rand01(), lvgm::rand01()*lvgm::rand01(), lvgm::rand01()*lvgm::rand01())));
                
                else if (choose_mat < 0.9)
                
                    list[size++] = new sphere(center, 0.2, new metal(rtvec(0.5*(1 + lvgm::rand01()), 0.5*(1 + lvgm::rand01()), 0.5*(1 + lvgm::rand01())), 0.5*lvgm::rand01()));
                
                else
                
                    list[size++] = new sphere(center, 0.2, new dielectric(1.5));
                
            
        
    
    list[size++] = new sphere(rtvec(0, 1, 0), 1.0, new dielectric(1.5));
    list[size++] = new sphere(rtvec(-4, 1, 0), 1.0, new lambertian(rtvec(0.4, 0.2, 0.1)));
    list[size++] = new sphere(rtvec(4, 1, 0), 1.0, new metal(rtvec(0.7, 0.6, 0.5), 0.));

    return new intersections(list, size);


void build_12_1()

    stds ofstream file("graph12-1.ppm");
    size_t W = 200, H = 120, sample = 100;

    if (file.is_open())
    
        file << "P3
" << W << " " << H << "
255
" << stds endl;

        intersect* world = random_sphere();

        rtvec lookfrom(13, 2, 3);
        rtvec lookat(0, 0, 0);
        float dist_to_focus = (lookfrom - lookat).normal();
        float aperture = 0.0;
        camera cma(lookfrom, lookat, rtvec(0, 1, 0), 20, rtvar(W) / rtvar(H), aperture, 0.7*dist_to_focus);

        for (int y = H - 1; y >= 0; --y)
            for (int x = 0; x < W; ++x)
            
                rtvec color;
                for (int cnt = 0; cnt < sample; ++cnt)
                
                    lvgm::vec2<rtvar> para
                        (lvgm::rand01() + x) / W,
                        (lvgm::rand01() + y) / H ;
                    color += lerp(cma.get_ray(para), world, 0);
                
                color /= sample;
                color = rtvec(sqrt(color.r()), sqrt(color.g()), sqrt(color.b()));    //gamma 校正
                int r = int(255.99 * color.r());
                int g = int(255.99 * color.g());
                int b = int(255.99 * color.b());
                file << r << " " << g << " " << b << stds endl;
            
        file.close();

        if (world)delete world;

        stds cout << "complished" << stds endl;
    
    else
        stds cerr << "open file error" << stds endl;



int main()

    build_12_1();

 

 感谢您的阅读,生活愉快~

 

raytracinginoneweekend超详解光线追踪1-7dielectric半径为负,实心球体镂空技巧(代码片段)

 今天讲这本书最后一种材质 Preface水,玻璃和钻石等透明材料是电介质。当光线照射它们时,它会分裂成反射光线和折射(透射)光线。处理方案:在反射或折射之间随机选择并且每次交互仅产生一条散射光线(实施方... 查看详情

springmvc常用注解超详解(代码片段)

文章目录SpringMVC常用注解超详解✨✨✨1.@RequestMapping注解1.1@RequestMapping注解的功能1.2@RequestMapping注解的位置1.3@RequestMapping注解的value属性1.4@RequestMapping注解的method属性1.5@RequestMapping注解的params属性&# 查看详情

java反射超详解✌(代码片段)

文章目录Java反射超详解✌1.反射基础1.1Class类1.2类加载2.反射的使用2.1Class对象的获取2.2Constructor类及其用法2.3Field类及其用法2.4Method类及其用法Java反射超详解✌1.反射基础Java反射机制是在程序的运行过程中,对于任何一个类&#... 查看详情

redis基础超详解(代码片段)

文章目录Redis基础超详解🍭🍭🍭1.概念2.Redis数据类型String(字符串)Hash(哈希)List(列表)Set(集合)zset(sortedset:有序集合)五大类型总结3.持久化为什么需要持久化? 查看详情

github隐藏使用技巧(超详解)

github使用说明方法一:首先打开github官网链接:github官网,在左上角搜索想要查询的内容方法二:直接打开其他人分享的github链接,:点击直接进入其他人的github项目查看别人的主页和项目上传自己的项目使用git下载github上的文件... 查看详情

2022mybatis-plus超详解

Mybatis-plus学习笔记1、创建数据库及表1.1、创建表CREATEDATABASE`mybatis_plus`;USE`mybatis_plus`;CREATETABLE`user`(`id`BIGINT(20)NOTNULLCOMMENT主键ID,`name`VARCHAR(30)NULLDEFAULTNULLCOMMENT姓名,`age`INT(11)NULLDEFAULTNULLC 查看详情

数据结构和算法超多图解,超详细,堆详解(代码片段)

🎈作者:Linux猿🎈简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊!🎈关注专栏:图解数据结构和算法 (... 查看详情

(超详解)springboot初级部分-概述-01

文章目录SpringBoot-概述-011.SpringBoot概念2.Spring缺点3.SpringBoot功能4.总结SpringBoot-概述-01该文章参考:黑马SpringBoot1.SpringBoot概念SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在... 查看详情

(超详解)springboot初级部分-概述-01

文章目录SpringBoot-概述-011.SpringBoot概念2.Spring缺点3.SpringBoot功能4.总结SpringBoot-概述-01该文章参考:黑马SpringBoot1.SpringBoot概念SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在... 查看详情

超详细ansible安装及模块详解

简介:ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的... 查看详情

jquery基础操作超详解✨(代码片段)

文章目录JQuery基础1.JQuery概述2.选择器操作3.DOM操作JQuery基础本章主要总结JQuery的一些基本操作。1.JQuery概述概念:一个JavaScript框架,简化JS开发。JQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的Jav... 查看详情

机器学习梯度下降法(超详解)

线性回归-梯度下降法前言1.全梯度下降算法(FG)2.随机梯度下降算法(SG)3.小批量梯度下降算法(mini-batch)4.随机平均梯度下降算法(SAG)5.梯度下降法算法比较和进一步优化5.1算法比较5.2梯度下... 查看详情

数据结构和算法超详细,超多图解,赫夫曼树详解

🎈作者:Linux猿🎈简介:CSDN博客专家🏆,华为云享专家🏆,数据结构和算法、C/C++、面试、刷题、Linux尽管咨询我,关注我,有问题私聊!🎈关注专栏:动图讲解数据结... 查看详情

深度学习正则化(超详解)(代码片段)

深度学习正则化学习目标1.偏差与方差1.1数据集划分1.2偏差与方差的意义1.3解决方法2.正则化(Regularization)2.1逻辑回归的L1与L2正则化2.2正则化项的理解2.3正则化为什么能够防止过拟合2.4tf.keras正则化API3.Droupout正则化3.1Inverteddroupout3.... 查看详情

(超详解)springboot初级部分-配置-03(代码片段)

文章目录SpringBoot-配置-031.配置文件分类2.yaml2.1yaml定义2.2yaml基本语法2.3yaml数据格式2.4yaml参数引用3.读取配置文件内容3.1@Value3.2Environment3.3@ConfigurationProperties4.profile4.1profile配置方式4.2profile激活方式5.内置配置加载顺序6.外部... 查看详情

超分辨率重建srgan详解-基于pytorch(代码片段)

好长一段时间没有写博客了,最近学习了超分辨率重构,曾经说过将来会写一些关于机器学习的博客的,今天就实现诺言吧。SRGAN论文地址代码参考了这篇博客:超分辨率——基于SRGAN的图像超分辨率重建(Pytorch实... 查看详情

juc中的aqs底层详细超详解(代码片段)

...唤醒?本文分享自华为云社区《JUC中的AQS底层详细超详解,剖析AQS设计中所需要考虑的各种问题!》,作者:breakDawn。j 查看详情

(超详解)springboot初级部分-快速入门-02(代码片段)

文章目录SpringBoot-快速入门-021.需求2.实现步骤2.1创建Maven项目2.2导入SpringBoot起步依赖2.3定义Controller2.4编写引导类2.5启动测试3.SpringInitializr创建SpringBoot工程4.SpringBoot起步依赖原理分析5.总结SpringBoot-快速入门-02该文章参考:黑... 查看详情