| import React, { useState, useEffect } from 'react'; |
| import PanelContainer from '../ui/PanelContainer'; |
| import GlowingBox from '../ui/GlowingBox'; |
| import { RepeatIcon, Undo2, ArrowLeft } from 'lucide-react'; |
|
|
| const BackpropagationPanel: React.FC = () => { |
| const [animationStep, setAnimationStep] = useState(0); |
| const [isAnimating, setIsAnimating] = useState(true); |
| |
| |
| useEffect(() => { |
| if (!isAnimating) return; |
| |
| const interval = setInterval(() => { |
| setAnimationStep(prev => (prev + 1) % 4); |
| }, 1200); |
| |
| return () => clearInterval(interval); |
| }, [isAnimating]); |
| |
| return ( |
| <PanelContainer |
| title="Learning via Backpropagation" |
| description="The CNN learns by comparing its predictions with the true labels, calculating the error, and then propagating this error backward through the network to update weights." |
| panelNumber={7} |
| > |
| <div className="flex flex-col items-center"> |
| <div className="w-full max-w-[800px] relative"> |
| {/* Neural network with backpropagation */} |
| <div className="relative w-full h-[300px] bg-gray-900/30 rounded-lg border border-gray-800"> |
| {/* Output neurons */} |
| <div className="absolute right-[15%] top-0 bottom-0 flex flex-col justify-center space-y-1"> |
| {Array(5).fill(0).map((_, i) => ( |
| <div |
| key={i} |
| className={`w-5 h-5 rounded-full ${ |
| i === 2 ? 'bg-green-500 shadow-md shadow-green-500/50' : |
| 'bg-pink-500 shadow-md shadow-pink-500/50' |
| } flex items-center justify-center text-[10px] font-bold`} |
| > |
| {i} |
| </div> |
| ))} |
| </div> |
| |
| {/* Hidden layers */} |
| <div className="absolute left-[50%] top-0 bottom-0 flex flex-col justify-center space-y-1"> |
| {Array(6).fill(0).map((_, i) => ( |
| <div |
| key={i} |
| className={`w-5 h-5 rounded-full bg-purple-500 shadow-md shadow-purple-500/50 ${ |
| animationStep === 2 && 'ring-2 ring-red-500 ring-offset-1 ring-offset-gray-900' |
| }`} |
| ></div> |
| ))} |
| </div> |
| |
| {/* Input neurons */} |
| <div className="absolute left-[15%] top-0 bottom-0 flex flex-col justify-center space-y-1"> |
| {Array(8).fill(0).map((_, i) => ( |
| <div |
| key={i} |
| className={`w-5 h-5 rounded-full bg-blue-500 shadow-md shadow-blue-500/50 ${ |
| animationStep === 3 && 'ring-2 ring-red-500 ring-offset-1 ring-offset-gray-900' |
| }`} |
| ></div> |
| ))} |
| </div> |
| |
| {/* Error indicator */} |
| <div className={`absolute right-[5%] top-1/2 transform -translate-y-1/2 |
| transition-opacity duration-500 ${animationStep === 0 ? 'opacity-100' : 'opacity-0'}`} |
| > |
| <GlowingBox color="from-red-500 to-red-600" className="p-1"> |
| <div className="px-3 py-1 text-sm text-red-200"> |
| Error: 0.42 |
| </div> |
| </GlowingBox> |
| </div> |
| |
| {/* Backpropagation animation */} |
| <svg className="absolute inset-0 w-full h-full pointer-events-none"> |
| <defs> |
| <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" |
| markerWidth="4" markerHeight="4" |
| orient="auto-start-reverse"> |
| <path d="M 0 0 L 10 5 L 0 10 z" fill={animationStep > 0 ? "rgba(239, 68, 68, 0.7)" : "rgba(139, 92, 246, 0.3)"} /> |
| </marker> |
| </defs> |
| |
| <g> |
| {/* Forward connections */} |
| <path |
| d="M 15% 150 C 30% 150, 35% 150, 50% 150" |
| stroke="rgba(139, 92, 246, 0.3)" |
| strokeWidth="20" |
| fill="none" |
| strokeLinecap="round" |
| opacity={animationStep === 0 ? "1" : "0.3"} |
| /> |
| |
| <path |
| d="M 50% 150 C 65% 150, 70% 150, 85% 150" |
| stroke="rgba(139, 92, 246, 0.3)" |
| strokeWidth="20" |
| fill="none" |
| strokeLinecap="round" |
| opacity={animationStep === 0 ? "1" : "0.3"} |
| /> |
| |
| {/* Backward connections with arrows */} |
| <path |
| d="M 85% 150 C 70% 150, 65% 150, 50% 150" |
| stroke={animationStep >= 1 ? "rgba(239, 68, 68, 0.4)" : "transparent"} |
| strokeWidth="4" |
| fill="none" |
| markerEnd="url(#arrow)" |
| strokeDasharray="6,3" |
| strokeLinecap="round" |
| /> |
| |
| <path |
| d="M 50% 150 C 35% 150, 30% 150, 15% 150" |
| stroke={animationStep >= 2 ? "rgba(239, 68, 68, 0.4)" : "transparent"} |
| strokeWidth="4" |
| fill="none" |
| markerEnd="url(#arrow)" |
| strokeDasharray="6,3" |
| strokeLinecap="round" |
| /> |
| </g> |
| </svg> |
| |
| {/* Weight update indicators */} |
| <div className={`absolute left-[35%] top-1/4 transform -translate-x-1/2 |
| transition-opacity duration-300 ${animationStep === 3 ? 'opacity-100' : 'opacity-0'}`} |
| > |
| <div className="px-2 py-1 bg-blue-900/70 rounded text-xs text-blue-200 border border-blue-700"> |
| Update weights |
| </div> |
| </div> |
| |
| <div className={`absolute left-[65%] top-1/4 transform -translate-x-1/2 |
| transition-opacity duration-300 ${animationStep === 2 ? 'opacity-100' : 'opacity-0'}`} |
| > |
| <div className="px-2 py-1 bg-blue-900/70 rounded text-xs text-blue-200 border border-blue-700"> |
| Update weights |
| </div> |
| </div> |
| |
| {/* Step indicators at bottom */} |
| <div className="absolute bottom-4 left-0 right-0 flex justify-center space-x-4"> |
| <div className={`px-3 py-1 rounded text-xs ${ |
| animationStep === 0 ? 'bg-blue-500 text-white' : 'bg-gray-800 text-gray-400' |
| }`}>Forward Pass</div> |
| <div className={`px-3 py-1 rounded text-xs ${ |
| animationStep === 1 ? 'bg-red-500 text-white' : 'bg-gray-800 text-gray-400' |
| }`}>Calculate Error</div> |
| <div className={`px-3 py-1 rounded text-xs ${ |
| animationStep >= 2 ? 'bg-red-500 text-white' : 'bg-gray-800 text-gray-400' |
| }`}>Backward Pass</div> |
| </div> |
| </div> |
| |
| <button |
| className="mt-4 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-md text-sm mx-auto block" |
| onClick={() => setIsAnimating(!isAnimating)} |
| > |
| {isAnimating ? 'Pause Animation' : 'Resume Animation'} |
| </button> |
| </div> |
| |
| <div className="mt-12 grid grid-cols-1 md:grid-cols-2 gap-6 w-full max-w-[800px]"> |
| <div className="bg-gray-800/60 rounded-lg p-5 border border-gray-700"> |
| <div className="flex items-center mb-3"> |
| <ArrowLeft size={18} className="text-red-400 mr-2 transform rotate-180" /> |
| <h4 className="text-lg font-semibold text-red-300">Backpropagation</h4> |
| </div> |
| <p className="text-sm text-gray-300"> |
| Backpropagation calculates how much each neuron's weight contributed to the output error. |
| It then adjusts these weights to minimize the error in future predictions, using the chain |
| rule of calculus to distribute error responsibility throughout the network. |
| </p> |
| </div> |
| |
| <div className="bg-gray-800/60 rounded-lg p-5 border border-gray-700"> |
| <div className="flex items-center mb-3"> |
| <RepeatIcon size={18} className="text-green-400 mr-2" /> |
| <h4 className="text-lg font-semibold text-green-300">Gradient Descent</h4> |
| </div> |
| <p className="text-sm text-gray-300"> |
| The network uses gradient descent to adjust weights in the direction that reduces error. |
| By repeatedly processing many examples and making small weight updates, the model gradually |
| improves its ability to recognize patterns and make accurate predictions. |
| </p> |
| </div> |
| </div> |
| |
| <div className="mt-8 p-5 bg-gradient-to-r from-blue-900/30 to-purple-900/30 rounded-lg border border-blue-800/50 w-full max-w-[800px]"> |
| <h3 className="text-xl font-semibold text-blue-300 mb-3">Key CNN Components Recap</h3> |
| <div className="flex flex-wrap gap-3"> |
| <div className="bg-gray-900/60 rounded-lg px-3 py-2 text-sm text-blue-300 border border-gray-800"> |
| Input Layer |
| </div> |
| <div className="bg-gray-900/60 rounded-lg px-3 py-2 text-sm text-purple-300 border border-gray-800"> |
| Convolutional Layers |
| </div> |
| <div className="bg-gray-900/60 rounded-lg px-3 py-2 text-sm text-cyan-300 border border-gray-800"> |
| Activation Functions |
| </div> |
| <div className="bg-gray-900/60 rounded-lg px-3 py-2 text-sm text-teal-300 border border-gray-800"> |
| Pooling Layers |
| </div> |
| <div className="bg-gray-900/60 rounded-lg px-3 py-2 text-sm text-pink-300 border border-gray-800"> |
| Fully Connected Layers |
| </div> |
| <div className="bg-gray-900/60 rounded-lg px-3 py-2 text-sm text-green-300 border border-gray-800"> |
| Output Layer |
| </div> |
| <div className="bg-gray-900/60 rounded-lg px-3 py-2 text-sm text-red-300 border border-gray-800"> |
| Backpropagation |
| </div> |
| </div> |
| </div> |
| </div> |
| </PanelContainer> |
| ); |
| }; |
|
|
| export default BackpropagationPanel; |