`

多线程摘录 008

阅读更多

* !!! synchronized使得在等待锁定的线程无法被中断, 也无法因为超时而返回. 这是JDK5重新引入ReentrantLock的主要原因

* ReentrantLock的典型使用风格
Lock lock = new ReentrantLock();
...
lock.lock();
try {
    // update object state
    // catch exceptions and restore invariants if necessary
} finally {
    lock.unlock();
}

* 下面是一段利用ReentrantLock.tryLock()来尝试锁定多个资源的代码, 只要其中有一个资源没有锁定, 就不断尝试下一次去获取锁定. 虽然获得了更多的控制如超时, 重新尝试甚至加入异常处理, 然而代码却比使用synchronized来的复杂
public boolean transferMoney(Account fromAcct,
                             Account toAcct,
                             DollarAmount amount,
                             long timeout,
                             TimeUnit unit)
        throws InsufficientFundsException, InterruptedException {
    long fixedDelay = getFixedDelayComponentNanos(timeout, unit);
    long randMod = getRandomDelayModulusNanos(timeout, unit);
    long stopTime = System.nanoTime() + unit.toNanos(timeout);

    while (true) {
        if (fromAcct.lock.tryLock()) {
        //尝试锁定, 如果成功就一定进入, 并且会执行finally块解锁
            try {
                if (toAcct.lock.tryLock()) {
                    try {
                        if (fromAcct.getBalance().compareTo(amount)
                                < 0)
                            throw new InsufficientFundsException();
                        else {
                            fromAcct.debit(amount);
                            toAcct.credit(amount);
                            return true;
                        }
                    } finally {
                        toAcct.lock.unlock();
                    }
                 }
             } finally {
                 fromAcct.lock.unlock();
             }
         }
         if (System.nanoTime() < stopTime)
             return false;
         NANOSECONDS.sleep(fixedDelay + rnd.nextLong() % randMod);
     }
}

* 仍然回到一个我们初始的问题:
既然是锁定, 那么我们锁定的对象是什么? 因为使用了ReentrantLock, 没有办法显式去指定被锁定对象, 而是对ReentrantLock内部的某个对象锁定, 不像synchronized(xxx)来指定获取对xxx的锁定, 这个时候, 就要求ReentrantLock是被多个线程共享的, 举一个很简单的例子, 朋友请吃饭, 却只有一个锅汤和一个勺子, 那么这N个线程都需要共享这个勺子:

public class Lunch {
    private ReentrantLock scoop = new ReentrantLock();

    public boolean dip() {
        try {
            scoop.lockInterruptibly();
        } catch (InterruptedException e) {
            Logger.log("someone call me for better food ~~~ ");
            return false;
        }

        Logger.log("hah, I got the scoop");
        try {
            // suppose we need 5s to dip the soup
            try {
                Thread.sleep(5000);
            } catch (InterruptedException i) {
                Logger.log("someone rob my scoop, 55~~~ ");
                return false;
            }
            Logger.log("I got delicious food ");
        } finally {
            scoop.unlock();
        }
        return true;
    }
}

public class Buddy extends Thread {
    private final Lunch lunch;
    public Buddy(Lunch lunch, String name) {
        this.lunch = lunch;
        this.setName(name);
    }
    public void run() {
        while (!lunch.dip()) {
            Logger.log("I will wait for a while to dip");
            try {
                Thread.sleep(100);
            } catch (InterruptedException ignore) {}
        }
    }
   
}


public class Party {
    public static void main(String[] args) throws Exception {
        Lunch lunch = new Lunch();
       
        /*new threads MUST share the same lunch instance*/
        Buddy titi= new Buddy(lunch, "titi");
        Buddy michael = new Buddy(lunch, "michael");
        Buddy ting= new Buddy(lunch, "ting");

        titi.start();
        Thread.sleep(100);
        michael.start();
        ting.start();
       
        Thread.sleep(1000);

        // why still hanging? rob him
        titi.interrupt();

        // ask michael to other food
        michael.interrupt();
    }
}

* 锁的公平性
所谓公平性, 就是按照线程访问共享资源的到达顺序来先后访问.如果任由线程自由竞争, 就是不公平. 然而, 公平性的意义可能不大, 而且浪费了太大的代价来维护这个顺序(线程调度的代价). ReentrantLock默认采用的是unfair策略, 也就是由线程自由竞争. 当然也允许使用设置公平策略.

有一种情况可以解释为什么不公平的锁性能更好. 例如, 线程A锁定了资源X, 线程B在等候, 当A完成自己的工作后, 通知B, 然后B被唤醒, 但是如果在A释放锁定情况下, 线程C刚刚到来, 发现可以锁定, 并且在B被唤醒的期间完成了工作, 释放锁定, 最后B再进行操作. 这是一个双赢的结果, 自然吞吐量就上去了. 如果采用公平策略, 那么C必须要排队在B之后.

   锁定 工作   释放
A: |~~~~~~~~~~~~>
   等待         唤醒            锁定 工作       释放
B: -------------|...............|~~~~~~~~~~~~~~~~>
                到达,锁定    释放
C:              |~~~~~~~~~~~~>


* 悲观锁synchronized和ReentrantLock的比较
1) synchronized更简单, 而且一直被使用, 至少编译器保证不会语法出错
2) ReentrantLock是一个危险的工具, 最常见的是忘记使用try-finally去执行unlock, 这样就为并发处理埋下隐患
3) ReentrantLock提供了更高级的功能: 超时, 响应中断, 公平性, 非阻塞锁定, 但是如果不需要这些特性, 为什么不使用synchronized?
4) 在JDK5的环境下, synchronized可以被JVM检测到死锁, 这些信息能被反映在线程的dump日志里面, 但JVM对ReentrantLock一无所知
5) 应该只在synchronized造成非常大的性能瓶颈的情况下才采用ReentrantLock

* ReadWriteLock
ReentrantLock是一种标准的互斥体(mutex)的实现, 但是对于"read-most"模式的共享资源, 互斥的方式极大的限制了性能, 这也是为什么有ReadWriteLock的原因

ReadWriteLock的机制很简单, 允许多个线程以读到方式访问, 但只允许一个线程以写的方式访问. 当要写入时, 一直等待到所有读的线程退出; 如果线程需要读取而又发现有线程中写入, 则一直等待写线程退出.

public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}

ReadWriteLock是一个接口, 显然, 它允许多种实现. 那么, 实现类可以选择哪些策略呢?
1) 读优先还是写优先? 比如当'写线程'释放了锁定, 如果在此前已经有读/写线程排队等待, 那么下一步应该读线程优先获得锁定呢, 还是写线程?
2) 是否允许临时读线程"闯入"? 比如当线程释放了锁定, 如果在此前已经有写线程排队等待, 那么这个新来的读线程是否可以跳过写线程直接去锁定还是排在写线程后面?
3) 可重入性
4) 升级降级. 一个正在写的线程能否降级为"读"锁定, 或者反过来升级.

ReentrantReadWriteLock:
如果设置了公平性: 对于1), 会倾向于分配锁定给等待时间最长的线程, 不过是读还是写. 对于2), 读线程会排到写线程后; 如果是自由竞争, 任何访问顺序都不保证; 允许降级, 不允许升级

* 代码: 用ReentrantReadWriteLock来保证HashMap的并发访问
public class ReadWriteMap<K,V> {
    private final Map<K,V> map;
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock r = lock.readLock();
    private final Lock w = lock.writeLock();

    public ReadWriteMap(Map<K,V> map) {
        this.map = map;
    }

    public V put(K key, V value) {
        w.lock();
        try {
            return map.put(key, value);
        } finally {
            w.unlock();
        }
    }
    // Do the same for remove(), putAll(), clear()

    public V get(Object key) {
        r.lock();
        try {
            return map.get(key);
        } finally {
            r.unlock();
        }
    }
    // Do the same for other read-only Map methods
}
只是演示如何使用ReentrantReadWriteLock. 实际上, ConcurrentHashMap的性能以及足够好.

测试表明在中等并发以以上的情况下, ReentrantReadWriteLock的吞吐量是ReentrantLock的3倍

* 和状态相关的线程设计
很多实际情况中, 要执行某些操作, 必须先满足某些前提条件. 如果前提条件不满足, 那么有两种处理方法, 一是直接返回失败的结果, 一是等待, 知道满足为止. JDk5提供了Condition类, 并且可以和Lock相关.

我们看一下使用"等待前提条件满足"策略的基本思路

获取对前提条件对象的锁定        //当然,是用来检测到
while(前提条件不满足) {
    - 释放锁定                  //如果不释放,就无法被其他线程修改
    - 等待                      //自然是等待其他线程的通知了
                                //可以有多种方式, 比如超时, 定时
    - 某些异常处理              //比如, 当前线程被中断了
    - 重新获取锁定              //
}

在JDK5里面, 可以这样做
Condition c = ReentrantLock.newCondition();
ReentrantLock.lock();
while (!isPreconditionSatisfied) {
    c.await();                  //这一行代码搞定了上面的所有要求
}
try{ ... } finally{ReentrantLock.unlock();}

这种代码行为是否似曾相识? 很像BlockingQueue吧...
再想想Latch, 是不是也有这种判断? 但Latch的不同在于, 一点状态被修改, 就在不能回复

考虑一下如果我们使用直接返回失败结果的方式, 弊端之一, 客户端必须不断尝试去重新测试前提条件是否满足, 这样会很浪费CPU, 但是我们可以让线程休眠啊? 这是弊端之二, 因为线程可能睡过头, 结果就是响应时间长了. 当然这个不算是什么太大的问题, 除非这个客户端被连续使用N次...

任何java对象都能作为一个锁, 也能作为一个"条件队列", 即让其他线程都进入"队列"等待通知, 来判断前提条件是否成立

Object.wait atomically releases the lock and asks the OS to suspend the current thread, allowing other threads to acquire the lock and therefore modify the object state. Upon waking, it reacquires the lock before returning
很简单吧, Object.wait方法就实现了上面的几点前提条件的要求

直接用java Object的API来实现, 当然了, 实际当中可能还需要更实用的方法, 比如包括可以超时的put/take方法
public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {
    ...
    public synchronized void put(V v) throws InterruptedException {
        while (isFull())
            wait();
        doPut(v);
        notifyAll();
    }

    public synchronized V take() throws InterruptedException {
        while (isEmpty())
            wait();
        V v = doTake();
        notifyAll();
        return v;
    }
}

或者, 更进一步的小优化
public static final Object lock = new Object();
void stateDependentMethod() throws InterruptedException {
    // condition predicate must be guarded by lock
    synchronized(lock) {
        while (!conditionPredicate())
            lock.wait();
        // object is now in desired state
    }
}

但是, 如果忘记测试前提条件或者测试有误, 会怎样? 可能会导致某些线程T一直等待下去!!! 因为如果再没有其他线程修改状态而发出通知的话, 这个线程T就挂了, 它需要额外的一个通知. 这种现象被称为"消失的信号"(Missed Signal), 与死锁类似. 当我们在代码里面使用 object.notity 而不是object.notifyAll的时候, 导致这种错误的几率非常大, 因为有多个线程都在等待, 而object.notity只是通知JVM唤醒了某一个线程, 除非是仅有一个线程中等待

当然, notifyAll的开销比notify稍微大一些. 也可以对notifyAll进行一点控制, 比如
public synchronized void put(V v) throws InterruptedException {
    while (isFull())
        wait();
    boolean wasEmpty = isEmpty();
    doPut(v);
    //留意这个判断, 如果本来队列就有元素, 说明没有线程在take, 即没有
    //线程中等待, 也就无需通知了
    if (wasEmpty)  
        notifyAll();
}

一个例子, 用来控制门的开和关, 有一些需要思考的地方
public class ThreadGate {
    // CONDITION-PREDICATE: opened-since(n) (isOpen || generation>n)
    @GuardedBy("this") private boolean isOpen;
    @GuardedBy("this") private int generation;

    public synchronized void close() {
        isOpen = false;
    }

    public synchronized void open() {
        ++generation;
        isOpen = true;
        notifyAll();
    }

    // BLOCKS-UNTIL: opened-since(generation on entry)
    public synchronized void await() throws InterruptedException {
        int arrivalGeneration = generation;
        while (!isOpen
            && arrivalGeneration == generation) {
            wait();
        }
    }
}

这个arrivalGeneration == generation判断很令人意外, 但却是必须的, 说明了并发的复杂性. 考虑下面的情景:
1) 当前门处于关闭状态, isOpen=false, generation=0
2) 当前线程A访问的时候, 获取了锁定, 当然!isOpen
&& arrivalGeneration == generation (为0), 两个条件都是成立的, A睡觉去了, 释放了锁定
3) 线程B来了, 取得锁定, 并且开了门: ThreadGate.open(), 这时generation=1, 然后唤醒一堆线程, 包括A
4) 在A被唤醒还没有获得锁定之前, 线程C快人一步, 并做了下面的事情: 先获取锁定, 然后关门, 那么 isOpen = false
5) 姗姗来迟的A终于获取到锁定, 发现isOpen=false, 但generation居然是1, 而自己手上的arrivalGeneration为0, 才明白不对劲, 不能继续睡了

即使A发现不对, 但isOpen仍旧是false, 是否应该继续wait? 问题出在哪里?
问题出在close(), 它修改了isOpen的值, 却没有通知其他线程

* 如果状态相关的并发类被继承?
A state-dependent class should either fully expose (and document) its waiting and notification protocols to subclasses, or prevent subclasses from participating in them at all

* "强制的"唤醒线程
AbstractQueuedSynchronizer, upon which most of the state-dependent classes in java.util.concurrent are built (see Section 14.4), exploits the concept of exit protocol. Rather than letting synchronizer classes perform their own notification, it instead requires synchronizer methods to return a value indicating whether its action might have unblocked one or more waiting threads. This explicit API requirement makes it harder to "forget" to notify on some state transitions.
大意是java.util.concurrent包的大部分类都是基于AbstractQueuedSynchronizer搭建的, 它要求这些并发类返回一个结果来表明需要唤醒一个或多个线程.

* 悲观条件队列(Intrinsic condition queues )的一个缺点就是, 悲观锁只能有一个条件队列, 这让一些不相关的线程也阻塞了. Lock和Condition 就是为解决这些问题设计的. 一个Lock可以有多个相关的Condition, 不同的线程可以分别在不同的Condition上等待, 知道满足为止. 当然还有其他的高级功能

Condition offers a richer feature set than intrinsic condition queues: multiple wait sets per lock, interruptible and uninterruptible condition waits, deadline-based waiting, and a choice of fair or nonfair queueing

public interface Condition {
    void await() throws InterruptedException;
    boolean await(long time, TimeUnit unit)
            throws InterruptedException;
    long awaitNanos(long nanosTimeout) throws InterruptedException;
    void awaitUninterruptibly();
    boolean awaitUntil(Date deadline) throws InterruptedException;

    void signal();
    void signalAll();
}

注意, Object的wait, notify, notifyAll 在Condition接口的等价方法为await, signal, signalAll, 但因为Condition同时也是Object的子类, 也有wait, notify, notifyAll, 不要用错了

下面的例子网上到处有
public class ConditionBoundedBuffer<T> {
    protected final Lock lock = new ReentrantLock();
    // CONDITION PREDICATE: notFull (count < items.length)
    private final Condition notFull    = lock.newCondition();
    // CONDITION PREDICATE: notEmpty (count > 0)
    private final Condition notEmpty = lock.newCondition();
    @GuardedBy("lock")
    private final T[] items = (T[]) new Object[BUFFER_SIZE];
    @GuardedBy("lock") private int tail, head, count;

    // BLOCKS-UNTIL: notFull
    public void put(T x) throws InterruptedException {
        lock.lock();
        try {
            while (count == items.length)
                notFull.await();
            items[tail] = x;
            if (++tail == items.length)
                tail = 0;
            ++count;
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    // BLOCKS-UNTIL: notEmpty
    public T take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0)
                notEmpty.await();
            T x = items[head];
            items[head] = null;
            if (++head == items.length)
                head = 0;
            --count;
            notFull.signal();
            return x;
        } finally {
            lock.unlock();
        }
    }
}

当然, Condition也不是Object.wait,notify,notifyAll的替代物, 按需使用嘛

* 剖析同步器
ReentrantLock 与 Semaphore 有许多相同点. Both classes act as a "gate", allowing only a limited number of threads to pass at a time; threads arrive at the gate and are allowed through (lock or acquire returns successfully), are made to wait (lock or acquire blocks), or are turned away (tryLock or tryAcquire returns false, indicating that the lock or permit did not become available in the time allowed). Further, both allow interruptible, uninterruptible, and timed acquisition attempts, and both allow a choice of fair or nonfair queueing of waiting threads.

ReentrantLock,Semaphore,CountDownLatch, ReentrantReadWriteLock, SynchronousQueue,FutureTask等都是基于AbstractQueuedSynchronizer 构建
转自:http://hi.baidu.com/iwishyou2/blog/item/5b6fb3ef88d51fe7ce1b3eff.html

分享到:
评论

相关推荐

    基于yolov3结合卡尔曼滤波匈牙利算法虚拟线圈的车流量检测python源码+项目说明.zip

    本项目专注于视频基的车辆跟踪与流量统计,依托深度学习技术,实时追踪路面车辆动态并精准统计各车道车流量。该项目通过以下核心步骤高效处理输入视频数据: 高精度目标检测:采用YOLOv3模型,凭借其卓越的实时性与准确性,快速识别视频中的车辆目标,为后续追踪奠定坚实基础。 稳定目标追踪:集成SORT(Simple Online and Realtime Tracking)算法,结合卡尔曼滤波器预测车辆未来位置,同时运用匈牙利算法优化目标间的匹配,实现连续、稳定的车辆追踪,有效应对遮挡、交叉等复杂场景。 智能车流量统计:借鉴虚拟线圈概念,巧妙设计算法以监测穿越预设区域的车辆,自动计数并准确统计各车道车流量,为交通管理与分析提供可靠数据支持。 整体而言,本项目通过融合先进的目标检测与追踪技术,结合创新的流量统计方法,构建了一个高效、精准的实时车辆跟踪与流量统计系统,为智慧交通领域的发展贡献力量。

    本科毕业设计--基于深度学习的人脸面部表情识别.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    雷电模拟器改成真机环境

    在Android系统中,模拟器通常会被识别为非真实的设备,这可能导致某些应用或服务无法正常运行,尤其是那些需要硬件信息或root权限的应用。改真机环境意味着通过技术手段使模拟器的行为更接近真实的Android设备,包括模拟设备硬件信息、IMEI、MAC地址等,以绕过检测并提升兼容性。LSPSED(Linux System Property Setter and Editor)模块是Magisk的一个扩展,专门用于修改Android系统的系统属性。通过LSPSED,我们可以更改设备的各种系统属性,如设备型号、制造商信息等,这些修改对于使模拟器看起来更像真实设备至关重要。在使用过程中,还需要添加几个机型模块,这些模块通常包含了特定设备的系统配置信息,如设备代号、硬件信息等。通过安装这些模块,雷电模拟器可以模仿各种流行的Android设备,进一步提高应用的兼容性和真实性。

    CenterNet 部署版本,便于移植不同平台(onnx、tensorRT、rknn、Horizon)

    CenterNet 是一种用于目标检测的神经网络架构,它的核心思想是利用目标的中心点作为检测的关键信息。这种方法与传统的目标检测方法(如基于边界框的方法)有所不同,因为它不直接预测目标的边界框,而是预测目标的中心点坐标和目标的宽度与高度。 CenterNet 的主要特点包括: 1. **中心点预测**:网络输出目标的中心点坐标,以及目标的宽度和高度。 2. **热图(Heatmap)**:网络生成一个热图,其中每个像素点的值表示该点成为目标中心点的概率。 3. **回归任务**:除了中心点坐标,网络还需要预测目标的宽度和高度,这通常通过预测中心点周围的偏移量来实现。 4. **多任务学习**:CenterNet 通常会同时预测目标的类别、中心点坐标、宽度、高度以及目标的旋转角度(在某些变体中)。 5. **端到端训练**:CenterNet 可以直接在最终的目标检测任务上进行端到端的训练,无需复杂的区域提议网络(Region Proposal Network, RPN)或锚点(anchor)机制。 6. **高效性**:由于省略了传统目标检测中的一些步骤,CenterNe

    CSP-J是计算机科学学科相关的青少年科技爱好者等级考试.docx

    CSP-J是计算机科学学科相关的青少年科技爱好者等级考试,全称为青少年软件编程等级考试。以下是对CSP-J的详细介绍: 一、考试背景与目的 CSP-J考试是由全国青少年软件编程等级考试标准工作组制定,并得到中国电子学会的认可,旨在培养青少年计算机科学素养和编程能力。通过参加这一考试,青少年可以检验自己的学习成果,增强自信心和竞争力,同时为他们未来在计算机科学领域的深入学习和职业发展打下坚实的基础。 二、考试内容与形式 CSP-J考试主要面向入门级别的青少年,考察内容侧重于计算机基础知识和算法的理解。考试形式分为初赛(笔试)和复赛(机试),即CSP-J1与CSP-J2。 初赛(CSP-J1):侧重于理论知识的考核,包括计算机基础知识、算法基本概念等,以笔试形式进行。 复赛(CSP-J2):更侧重于上机编程能力的实践考察,要求参赛者在计算机上完成编程任务。 参赛者必须先参加初赛,并达到一定的分数方可参加复赛。 三、报名与参与 报名方式:CSP-J/S认证面向所有对计算机科学有兴趣的青少年开放,报名和认证过程均在网上进行。认证点由CCF(中国计算机学会)授权的CSP非专业级别省认证组

    机械课程设计 X Y双坐标联动数控工作台设计(全套图纸).doc

    机械课程设计 X Y双坐标联动数控工作台设计(全套图纸).doc

    基于BERT模型的深度学习中文文本分类实现,包含大约20000条新闻的训练和测试集,包装有简单HTTP接口可供调用。.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    MySQL数据库的安装教程与使用心得

    MySQL数据库的安装教程与使用心得

    直线的点斜式方程与斜截式方程.ppt

    直线的点斜式方程与斜截式方程.ppt

    人工智能技术面试指南人工智能技术面试指南

    内容概要:本文提供了一套与人工智能相关的面试问题及其详细解答,涉及的基础知识点有机器学习的概念及其实现形式(例如监督学习与无监督学习)、常见优化算法的应用(比如梯度下降法);探讨模型评估指标的选择(如分类任务的精度指标、回归模型的平方损失等)、解决过拟合现象的技术措施等,并具体剖析了深度学习尤其是卷积神经网络的工作机制。这份材料是应聘者准备技术岗特别是AI相关职位的理想助手。 适用人群:求职时希望专注于 AI 技术领域的人群;具有一定 AI 背景的研究人员和技术从业者。 使用场景及目标:适合于复习与巩固基本技能,在面试过程中表现出较强的专业能力和理解力。 其他说明:本资料全面介绍了人工智能基础知识、主要工具技术和常用评价方式的相关概念和技巧,有助于应聘者更好地应对技术岗位的考核与挑战。

    【5层】公司办公楼全套设计+++(3156平,含计算书、建筑图,结构图、实习报告,PKPM,答辩PPT).zip

    【5层】公司办公楼全套设计+++(3156平,含计算书、建筑图,结构图、实习报告,PKPM,答辩PPT) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。

    JavaEE大作业 计算机学科竞赛网站及报名系统

    JavaEE制作学科竞赛报名系统的意义在于:便利性:提供了一个集中、统一的平台,方便学生和教师在线完成报名、缴费、上传资料等操作,避免了繁琐的手工流程,提高了工作效率。

    电子设计论文文档资料鸟鸣报警器电子设计论文文档资料鸟鸣报警器

    电子设计论文文档资料鸟鸣报警器电子设计论文文档资料鸟鸣报警器

    java-ssh-jsp-mysql图书管理系统实现源码(项目源码-说明文档)

    网站的首页,主要实现了对首页信息的展示发布,能够展示最新的图书信息,并能查看相关的新闻信息,电子书的下载等 网站的后台登录主要实现了后台信息的登录,管理员输入用户名和密码就可以登录进入后台进行相关的操作 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssh 前端技术:jsp 关键技术:jsp、spring、ssm、ssh、MYSQL、MAVEN 数据库工具:Navicat、SQLyog

    美国人如何为电动汽车充电(英文).pdf

    这份文件是《美国电动汽车快速充电走廊路线图2023》,主要分析了美国电动汽车(EV)长途充电基础设施的现状与未来规划,并提出了具体的建议措施。以下是核心内容提炼: 项目背景与目的: 背景:随着电动汽车市场的快速增长,建设全面的长途充电基础设施成为迫切需求。 目的:制定美国电动汽车快速充电走廊路线图,确保电动汽车车主能够顺畅进行长途旅行。 现有充电站情况: 现状:目前已有509个符合NEVI(国家电动汽车基础设施)标准的公共非特斯拉充电站,即“走廊就绪”充电站。 问题:部分走廊区段充电站间距超过50英里,不满足NEVI要求,存在网络缺口。 推荐充电站布局: 战略部署:建议在特定位置增设1,084个充电站,以解决现有网络缺口。 布局原则:根据NEVI指南,确保充电站间距不超过50英里,以达到全面建成的标准。 充电站类型与成本: 类别:包括高速公路充电站和其他公路充电站,分别满足不同路段的充电需求。 成本:具体成本因州而异,需考虑州际充电站和公路充电站的建设成本。 资金来源与分配: 资金来源:NEVI计划将在2022年至2026年间提供总计50亿美元的资金支持。 资金分配:各州获得的资金额

    基于JSP的房产中介系统的设计与实现(源代码+论文).zip

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 、本项3目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。

    基于Python实现多线程知乎用户爬虫.zip

    基于Python实现多线程知乎用户爬虫.zip

    基于统计机器学习模型(最大熵模型、马尔科夫模型、条件随机场)和深度学习模型LSTM-CRF的中文分词(BIO).zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    小程序毕业设计-基于微信小程序的移动学习平台的设计与实现+ssm(包括源码,数据库,教程).zip

    Java 毕业设计,小程序毕业设计,小程序课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 1. 技术组成 前端: 小程序 后台框架:SSM/SpringBoot(如果有的话) 开发环境:idea,微信开发者工具 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库可视化工具:使用 Navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven

    基于thinkphp+mysql实现的社区论坛源代码+数据库

    基于thinkphp+mysql实现的社区论坛源代码+数据库

Global site tag (gtag.js) - Google Analytics